diff --git a/README.md b/README.md index 7772e95..9540933 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ **Kirby: the CMS that adapts to any project, loved by developers and editors alike.** -The Plainkit is a minimal Kirby setup with the basics you need to start a project from scratch. It is the ideal choice if you are already familiar with Kirby and want to start step-by-step. +The Plainkit is a minimal Kirby setup with the basics you need to start a project from scratch. It is the ideal choice +if you are already familiar with Kirby and want to start step-by-step. You can learn more about Kirby at [getkirby.com](https://getkirby.com). ### Try Kirby for free -You can try Kirby and the Plainkit on your local machine or on a test server as long as you need to make sure it is the right tool for your next project. … and when you’re convinced, [buy your license](https://getkirby.com/buy). +You can try Kirby and the Plainkit on your local machine or on a test server as long as you need to make sure it is the +right tool for your next project. … and when you’re convinced, [buy your license](https://getkirby.com/buy). ### Get going @@ -20,15 +22,17 @@ If you are familiar with Git, you can clone Kirby's Plainkit repository from Git ## What's Kirby? -- **[getkirby.com](https://getkirby.com)** – Get to know the CMS. -- **[Try it](https://getkirby.com/try)** – Take a test ride with our online demo. Or download one of our kits to get started. -- **[Documentation](https://getkirby.com/docs/guide)** – Read the official guide, reference and cookbook recipes. -- **[Issues](https://github.com/getkirby/kirby/issues)** – Report bugs and other problems. -- **[Feedback](https://feedback.getkirby.com)** – You have an idea for Kirby? Share it. -- **[Forum](https://forum.getkirby.com)** – Whenever you get stuck, don't hesitate to reach out for questions and support. -- **[Discord](https://chat.getkirby.com)** – Hang out and meet the community. -- **[Mastodon](https://mastodon.social/@getkirby)** – Spread the word. -- **[Bluesky](https://bsky.app/profile/getkirby.com)** – Spread the word. +- **[getkirby.com](https://getkirby.com)** – Get to know the CMS. +- **[Try it](https://getkirby.com/try)** – Take a test ride with our online demo. Or download one of our kits to get + started. +- **[Documentation](https://getkirby.com/docs/guide)** – Read the official guide, reference and cookbook recipes. +- **[Issues](https://github.com/getkirby/kirby/issues)** – Report bugs and other problems. +- **[Feedback](https://feedback.getkirby.com)** – You have an idea for Kirby? Share it. +- **[Forum](https://forum.getkirby.com)** – Whenever you get stuck, don't hesitate to reach out for questions and + support. +- **[Discord](https://chat.getkirby.com)** – Hang out and meet the community. +- **[Mastodon](https://mastodon.social/@getkirby)** – Spread the word. +- **[Bluesky](https://bsky.app/profile/getkirby.com)** – Spread the word. --- diff --git a/assets/css/png4web.css b/assets/css/png4web.css index 282214d..f795304 100644 --- a/assets/css/png4web.css +++ b/assets/css/png4web.css @@ -2,133 +2,133 @@ * copyright (C) 2009-2013 Paolo Casaschi * see README file and http://pgn4web.casaschi.net * for credits, license and more details */ - @import url("../fonts/pgn4web-font-LiberationSans.css"); - @import url("../fonts/pgn4web-font-ChessSansUsual.css"); - - div, - span, - table, - tr, - td { - font-family: 'pgn4web Liberation Sans', sans-serif; - - /* fixes IE9 body css issue */ - } - - .boardTable { - border-style: double; - border-color: black; - border-width: 3px; - width: 600px; - height: 600px; - } - - .pieceImage { - width: 60px; - height: 60px; - } - - .whiteSquare, - .blackSquare, - .highlightWhiteSquare, - .highlightBlackSquare { - width: 55px; - height: 55px; - border-style: solid; - border-width: 1px; - } - - .whiteSquare, - .highlightWhiteSquare { - border-color: #EFF4EC; - background: #EFF4EC; - } - - .blackSquare, - .highlightBlackSquare { - border-color: #C6CEC3; - background: #C6CEC3; - } - - .highlightWhiteSquare, - .highlightBlackSquare { - border-style: inset; - border-color: gray; - } - - .selectControl { - /* a "width" attribute here must use the !important flag to override default settings */ - } - - .optionSelectControl { - } - - .buttonControlPlay, - .buttonControlStop, - .buttonControl { - /* a "width" attribute here must use the !important flag to override default settings */ - } - - .buttonControlSpace { - /* a "width" attribute here must use the !important flag to override default settings */ - } - - .searchPgnButton { - /* a "width" attribute here must use the !important flag to override default settings */ - } - - .searchPgnExpression { - /* a "width" attribute here must use the !important flag to override default settings */ - } - - .move, - .variation, - .comment { - line-height: 1.4em; - font-weight: normal; - font-size: 1.5rem; - font-family: 'pgn4web ChessSansUsual', 'pgn4web Liberation Sans', sans-serif; - } - - .move, - .variation, - .commentMove { - font-family: 'pgn4web ChessSansUsual', 'pgn4web Liberation Sans', sans-serif; - } - - a.move, - a.variation, - .commentMove { - white-space: nowrap; - } - - .move, - .variation { - text-decoration: none; - } - - a.move:hover, - a.variation:hover { - text-decoration: underline; - } - - .move { - color: #c6c6c6; - } - - .comment, - .variation, - .label { - color: gray; - } - - a.variation { - color: gray; - } - - .moveOn, - .variationOn { - background: #DAF4D7; - } +@import url("../fonts/pgn4web-font-LiberationSans.css"); +@import url("../fonts/pgn4web-font-ChessSansUsual.css"); + +div, +span, +table, +tr, +td { + font-family: 'pgn4web Liberation Sans', sans-serif; + + /* fixes IE9 body css issue */ +} + +.boardTable { + border-style: double; + border-color: black; + border-width: 3px; + width: 600px; + height: 600px; +} + +.pieceImage { + width: 60px; + height: 60px; +} + +.whiteSquare, +.blackSquare, +.highlightWhiteSquare, +.highlightBlackSquare { + width: 55px; + height: 55px; + border-style: solid; + border-width: 1px; +} + +.whiteSquare, +.highlightWhiteSquare { + border-color: #EFF4EC; + background: #EFF4EC; +} + +.blackSquare, +.highlightBlackSquare { + border-color: #C6CEC3; + background: #C6CEC3; +} + +.highlightWhiteSquare, +.highlightBlackSquare { + border-style: inset; + border-color: gray; +} + +.selectControl { + /* a "width" attribute here must use the !important flag to override default settings */ +} + +.optionSelectControl { +} + +.buttonControlPlay, +.buttonControlStop, +.buttonControl { + /* a "width" attribute here must use the !important flag to override default settings */ +} + +.buttonControlSpace { + /* a "width" attribute here must use the !important flag to override default settings */ +} + +.searchPgnButton { + /* a "width" attribute here must use the !important flag to override default settings */ +} + +.searchPgnExpression { + /* a "width" attribute here must use the !important flag to override default settings */ +} + +.move, +.variation, +.comment { + line-height: 1.4em; + font-weight: normal; + font-size: 1.5rem; + font-family: 'pgn4web ChessSansUsual', 'pgn4web Liberation Sans', sans-serif; +} + +.move, +.variation, +.commentMove { + font-family: 'pgn4web ChessSansUsual', 'pgn4web Liberation Sans', sans-serif; +} + +a.move, +a.variation, +.commentMove { + white-space: nowrap; +} + +.move, +.variation { + text-decoration: none; +} + +a.move:hover, +a.variation:hover { + text-decoration: underline; +} + +.move { + color: #c6c6c6; +} + +.comment, +.variation, +.label { + color: gray; +} + +a.variation { + color: gray; +} + +.moveOn, +.variationOn { + background: #DAF4D7; +} \ No newline at end of file diff --git a/assets/css/styles.css b/assets/css/styles.css index dd40b42..e8960e8 100644 --- a/assets/css/styles.css +++ b/assets/css/styles.css @@ -2,840 +2,1026 @@ @layer properties; @layer theme, base, components, utilities; @layer theme { - :root, :host { - --font-sans: 'Ubuntu', sans-serif; - --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', + :root, :host { + --font-sans: 'Ubuntu', sans-serif; + --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; - --color-blue-500: oklch(62.3% 0.214 259.815); - --color-blue-600: oklch(54.6% 0.245 262.881); - --color-pink-500: oklch(65.6% 0.241 354.308); - --color-gray-100: oklch(96.7% 0.003 264.542); - --color-gray-500: oklch(55.1% 0.027 264.364); - --color-gray-600: oklch(44.6% 0.03 256.802); - --color-gray-700: oklch(37.3% 0.034 259.733); - --color-gray-900: oklch(21% 0.034 264.665); - --color-white: #fff; - --spacing: 0.25rem; - --container-7xl: 80rem; - --text-sm: 0.875rem; - --text-sm--line-height: calc(1.25 / 0.875); - --text-base: 1rem; - --text-base--line-height: calc(1.5 / 1); - --text-lg: 1.125rem; - --text-lg--line-height: calc(1.75 / 1.125); - --text-4xl: 2.25rem; - --text-4xl--line-height: calc(2.5 / 2.25); - --font-weight-medium: 500; - --font-weight-bold: 700; - --radius-md: 0.375rem; - --radius-lg: 0.5rem; - --default-transition-duration: 150ms; - --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - --default-font-family: var(--font-sans); - --default-mono-font-family: var(--font-mono); - --color-sf_blau-500: #1d59a5; - --color-sf_blau-700: #184a89; - --color-sf_gelb-400: #f6b95f; - --color-sf_gelb-500: #f0ab38; - --color-sf_grau-50: #ededed; - --color-sf_grau-400: #717171; - --color-sf_grau-600: #4e4e4e; - --color-sf_grau-800: #404040; - } + --color-blue-500: oklch(62.3% 0.214 259.815); + --color-blue-600: oklch(54.6% 0.245 262.881); + --color-pink-500: oklch(65.6% 0.241 354.308); + --color-gray-100: oklch(96.7% 0.003 264.542); + --color-gray-500: oklch(55.1% 0.027 264.364); + --color-gray-600: oklch(44.6% 0.03 256.802); + --color-gray-700: oklch(37.3% 0.034 259.733); + --color-gray-900: oklch(21% 0.034 264.665); + --color-white: #fff; + --spacing: 0.25rem; + --container-7xl: 80rem; + --text-sm: 0.875rem; + --text-sm--line-height: calc(1.25 / 0.875); + --text-base: 1rem; + --text-base--line-height: calc(1.5 / 1); + --text-lg: 1.125rem; + --text-lg--line-height: calc(1.75 / 1.125); + --text-4xl: 2.25rem; + --text-4xl--line-height: calc(2.5 / 2.25); + --font-weight-medium: 500; + --font-weight-bold: 700; + --radius-md: 0.375rem; + --radius-lg: 0.5rem; + --default-transition-duration: 150ms; + --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + --default-font-family: var(--font-sans); + --default-mono-font-family: var(--font-mono); + --color-sf_blau-500: #1d59a5; + --color-sf_blau-700: #184a89; + --color-sf_gelb-400: #f6b95f; + --color-sf_gelb-500: #f0ab38; + --color-sf_grau-50: #ededed; + --color-sf_grau-400: #717171; + --color-sf_grau-600: #4e4e4e; + --color-sf_grau-800: #404040; + } } @layer base { - *, ::after, ::before, ::backdrop, ::file-selector-button { - box-sizing: border-box; - margin: 0; - padding: 0; - border: 0 solid; - } - html, :host { - line-height: 1.5; - -webkit-text-size-adjust: 100%; - tab-size: 4; - font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); - font-feature-settings: var(--default-font-feature-settings, normal); - font-variation-settings: var(--default-font-variation-settings, normal); - -webkit-tap-highlight-color: transparent; - } - hr { - height: 0; - color: inherit; - border-top-width: 1px; - } - abbr:where([title]) { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; - } - h1, h2, h3, h4, h5, h6 { - font-size: inherit; - font-weight: inherit; - } - a { - color: inherit; - -webkit-text-decoration: inherit; - text-decoration: inherit; - } - b, strong { - font-weight: bolder; - } - code, kbd, samp, pre { - font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace); - font-feature-settings: var(--default-mono-font-feature-settings, normal); - font-variation-settings: var(--default-mono-font-variation-settings, normal); - font-size: 1em; - } - small { - font-size: 80%; - } - sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; - } - sub { - bottom: -0.25em; - } - sup { - top: -0.5em; - } - table { - text-indent: 0; - border-color: inherit; - border-collapse: collapse; - } - :-moz-focusring { - outline: auto; - } - progress { - vertical-align: baseline; - } - summary { - display: list-item; - } - ol, ul, menu { - list-style: none; - } - img, svg, video, canvas, audio, iframe, embed, object { - display: block; - vertical-align: middle; - } - img, video { - max-width: 100%; - height: auto; - } - button, input, select, optgroup, textarea, ::file-selector-button { - font: inherit; - font-feature-settings: inherit; - font-variation-settings: inherit; - letter-spacing: inherit; - color: inherit; - border-radius: 0; - background-color: transparent; - opacity: 1; - } - :where(select:is([multiple], [size])) optgroup { - font-weight: bolder; - } - :where(select:is([multiple], [size])) optgroup option { - padding-inline-start: 20px; - } - ::file-selector-button { - margin-inline-end: 4px; - } - ::placeholder { - opacity: 1; - } - @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) { - ::placeholder { - color: currentcolor; - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, currentcolor 50%, transparent); - } + *, ::after, ::before, ::backdrop, ::file-selector-button { + box-sizing: border-box; + margin: 0; + padding: 0; + border: 0 solid; + } + + html, :host { + line-height: 1.5; + -webkit-text-size-adjust: 100%; + tab-size: 4; + font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); + font-feature-settings: var(--default-font-feature-settings, normal); + font-variation-settings: var(--default-font-variation-settings, normal); + -webkit-tap-highlight-color: transparent; + } + + hr { + height: 0; + color: inherit; + border-top-width: 1px; + } + + abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + } + + h1, h2, h3, h4, h5, h6 { + font-size: inherit; + font-weight: inherit; + } + + a { + color: inherit; + -webkit-text-decoration: inherit; + text-decoration: inherit; + } + + b, strong { + font-weight: bolder; + } + + code, kbd, samp, pre { + font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace); + font-feature-settings: var(--default-mono-font-feature-settings, normal); + font-variation-settings: var(--default-mono-font-variation-settings, normal); + font-size: 1em; + } + + small { + font-size: 80%; + } + + sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; + } + + sub { + bottom: -0.25em; + } + + sup { + top: -0.5em; + } + + table { + text-indent: 0; + border-color: inherit; + border-collapse: collapse; + } + + :-moz-focusring { + outline: auto; + } + + progress { + vertical-align: baseline; + } + + summary { + display: list-item; + } + + ol, ul, menu { + list-style: none; + } + + img, svg, video, canvas, audio, iframe, embed, object { + display: block; + vertical-align: middle; + } + + img, video { + max-width: 100%; + height: auto; + } + + button, input, select, optgroup, textarea, ::file-selector-button { + font: inherit; + font-feature-settings: inherit; + font-variation-settings: inherit; + letter-spacing: inherit; + color: inherit; + border-radius: 0; + background-color: transparent; + opacity: 1; + } + + :where(select:is([multiple], [size])) optgroup { + font-weight: bolder; + } + + :where(select:is([multiple], [size])) optgroup option { + padding-inline-start: 20px; + } + + ::file-selector-button { + margin-inline-end: 4px; + } + + ::placeholder { + opacity: 1; + } + + @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) { + ::placeholder { + color: currentcolor; + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, currentcolor 50%, transparent); + } + } + } + textarea { + resize: vertical; + } + + ::-webkit-search-decoration { + -webkit-appearance: none; + } + + ::-webkit-date-and-time-value { + min-height: 1lh; + text-align: inherit; + } + + ::-webkit-datetime-edit { + display: inline-flex; + } + + ::-webkit-datetime-edit-fields-wrapper { + padding: 0; + } + + ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field { + padding-block: 0; + } + + :-moz-ui-invalid { + box-shadow: none; + } + + button, input:where([type="button"], [type="reset"], [type="submit"]), ::file-selector-button { + appearance: button; + } + + ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { + height: auto; + } + + [hidden]:where(:not([hidden="until-found"])) { + display: none !important; } - } - textarea { - resize: vertical; - } - ::-webkit-search-decoration { - -webkit-appearance: none; - } - ::-webkit-date-and-time-value { - min-height: 1lh; - text-align: inherit; - } - ::-webkit-datetime-edit { - display: inline-flex; - } - ::-webkit-datetime-edit-fields-wrapper { - padding: 0; - } - ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field { - padding-block: 0; - } - :-moz-ui-invalid { - box-shadow: none; - } - button, input:where([type="button"], [type="reset"], [type="submit"]), ::file-selector-button { - appearance: button; - } - ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { - height: auto; - } - [hidden]:where(:not([hidden="until-found"])) { - display: none !important; - } } @layer utilities { - .invisible { - visibility: hidden; - } - .absolute { - position: absolute; - } - .relative { - position: relative; - } - .sticky { - position: sticky; - } - .inset-0 { - inset: calc(var(--spacing) * 0); - } - .top-0 { - top: calc(var(--spacing) * 0); - } - .top-2 { - top: calc(var(--spacing) * 2); - } - .left-0 { - left: calc(var(--spacing) * 0); - } - .z-0 { - z-index: 0; - } - .z-10 { - z-index: 10; - } - .z-50 { - z-index: 50; - } - .container { - width: 100%; - @media (width >= 40rem) { - max-width: 40rem; + .invisible { + visibility: hidden; } - @media (width >= 48rem) { - max-width: 48rem; + + .absolute { + position: absolute; } - @media (width >= 64rem) { - max-width: 64rem; + + .relative { + position: relative; } - @media (width >= 80rem) { - max-width: 80rem; + + .sticky { + position: sticky; } - @media (width >= 96rem) { - max-width: 96rem; + + .inset-0 { + inset: calc(var(--spacing) * 0); } - } - .mx-auto { - margin-inline: auto; - } - .mt-2 { - margin-top: calc(var(--spacing) * 2); - } - .mt-4 { - margin-top: calc(var(--spacing) * 4); - } - .mb-3 { - margin-bottom: calc(var(--spacing) * 3); - } - .mb-6 { - margin-bottom: calc(var(--spacing) * 6); - } - .ml-1 { - margin-left: calc(var(--spacing) * 1); - } - .block { - display: block; - } - .flex { - display: flex; - } - .hidden { - display: none; - } - .inline { - display: inline; - } - .h-4 { - height: calc(var(--spacing) * 4); - } - .h-6 { - height: calc(var(--spacing) * 6); - } - .h-10 { - height: calc(var(--spacing) * 10); - } - .h-18 { - height: calc(var(--spacing) * 18); - } - .h-24 { - height: calc(var(--spacing) * 24); - } - .h-auto { - height: auto; - } - .h-full { - height: 100%; - } - .w-3\/4 { - width: calc(3/4 * 100%); - } - .w-4 { - width: calc(var(--spacing) * 4); - } - .w-6 { - width: calc(var(--spacing) * 6); - } - .w-10 { - width: calc(var(--spacing) * 10); - } - .w-18 { - width: calc(var(--spacing) * 18); - } - .w-24 { - width: calc(var(--spacing) * 24); - } - .w-48 { - width: calc(var(--spacing) * 48); - } - .w-full { - width: 100%; - } - .max-w-7xl { - max-width: var(--container-7xl); - } - .rotate-180 { - rotate: 180deg; - } - .transform { - transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,); - } - .resize { - resize: both; - } - .flex-col { - flex-direction: column; - } - .items-baseline { - align-items: baseline; - } - .items-center { - align-items: center; - } - .justify-between { - justify-content: space-between; - } - .justify-center { - justify-content: center; - } - .gap-6 { - gap: calc(var(--spacing) * 6); - } - .gap-8 { - gap: calc(var(--spacing) * 8); - } - .space-y-1 { - :where(& > :not(:last-child)) { - --tw-space-y-reverse: 0; - margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse)); - margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse))); + + .top-0 { + top: calc(var(--spacing) * 0); } - } - .space-x-3 { - :where(& > :not(:last-child)) { - --tw-space-x-reverse: 0; - margin-inline-start: calc(calc(var(--spacing) * 3) * var(--tw-space-x-reverse)); - margin-inline-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-x-reverse))); + + .top-2 { + top: calc(var(--spacing) * 2); } - } - .space-x-4 { - :where(& > :not(:last-child)) { - --tw-space-x-reverse: 0; - margin-inline-start: calc(calc(var(--spacing) * 4) * var(--tw-space-x-reverse)); - margin-inline-end: calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-x-reverse))); + + .left-0 { + left: calc(var(--spacing) * 0); } - } - .overflow-hidden { - overflow: hidden; - } - .rounded-lg { - border-radius: var(--radius-lg); - } - .rounded-md { - border-radius: var(--radius-md); - } - .border { - border-style: var(--tw-border-style); - border-width: 1px; - } - .border-t { - border-top-style: var(--tw-border-style); - border-top-width: 1px; - } - .border-gray-700 { - border-color: var(--color-gray-700); - } - .bg-blue-500\/40 { - background-color: color-mix(in srgb, oklch(62.3% 0.214 259.815) 40%, transparent); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-blue-500) 40%, transparent); + + .z-0 { + z-index: 0; } - } - .bg-sf_grau-50 { - background-color: var(--color-sf_grau-50); - } - .bg-sf_grau-400 { - background-color: var(--color-sf_grau-400); - } - .bg-white { - background-color: var(--color-white); - } - .object-cover { - object-fit: cover; - } - .px-2 { - padding-inline: calc(var(--spacing) * 2); - } - .px-3 { - padding-inline: calc(var(--spacing) * 3); - } - .px-4 { - padding-inline: calc(var(--spacing) * 4); - } - .py-1 { - padding-block: calc(var(--spacing) * 1); - } - .py-2 { - padding-block: calc(var(--spacing) * 2); - } - .py-7 { - padding-block: calc(var(--spacing) * 7); - } - .py-16 { - padding-block: calc(var(--spacing) * 16); - } - .py-24 { - padding-block: calc(var(--spacing) * 24); - } - .pt-2 { - padding-top: calc(var(--spacing) * 2); - } - .pt-4 { - padding-top: calc(var(--spacing) * 4); - } - .pb-3 { - padding-bottom: calc(var(--spacing) * 3); - } - .pl-6 { - padding-left: calc(var(--spacing) * 6); - } - .text-center { - text-align: center; - } - .text-left { - text-align: left; - } - .font-sans { - font-family: var(--font-sans); - } - .text-4xl { - font-size: var(--text-4xl); - line-height: var(--tw-leading, var(--text-4xl--line-height)); - } - .text-base { - font-size: var(--text-base); - line-height: var(--tw-leading, var(--text-base--line-height)); - } - .text-lg { - font-size: var(--text-lg); - line-height: var(--tw-leading, var(--text-lg--line-height)); - } - .text-sm { - font-size: var(--text-sm); - line-height: var(--tw-leading, var(--text-sm--line-height)); - } - .font-bold { - --tw-font-weight: var(--font-weight-bold); - font-weight: var(--font-weight-bold); - } - .font-medium { - --tw-font-weight: var(--font-weight-medium); - font-weight: var(--font-weight-medium); - } - .text-gray-500 { - color: var(--color-gray-500); - } - .text-gray-600 { - color: var(--color-gray-600); - } - .text-gray-700 { - color: var(--color-gray-700); - } - .text-gray-900 { - color: var(--color-gray-900); - } - .text-sf_blau-500 { - color: var(--color-sf_blau-500); - } - .text-sf_grau-600 { - color: var(--color-sf_grau-600); - } - .text-sf_grau-800 { - color: var(--color-sf_grau-800); - } - .text-white { - color: var(--color-white); - } - .antialiased { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } - .opacity-0 { - opacity: 0%; - } - .opacity-50 { - opacity: 50%; - } - .shadow-lg { - --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - .shadow-xl { - --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - .transition-all { - transition-property: all; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .transition-colors { - transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .transition-transform { - transition-property: transform, translate, scale, rotate; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .duration-200 { - --tw-duration: 200ms; - transition-duration: 200ms; - } - .duration-500 { - --tw-duration: 500ms; - transition-duration: 500ms; - } - .group-hover\:visible { - &:is(:where(.group):hover *) { - @media (hover: hover) { - visibility: visible; - } + + .z-10 { + z-index: 10; } - } - .group-hover\:rotate-180 { - &:is(:where(.group):hover *) { - @media (hover: hover) { + + .z-50 { + z-index: 50; + } + + .container { + width: 100%; + @media (width >= 40rem) { + max-width: 40rem; + } + @media (width >= 48rem) { + max-width: 48rem; + } + @media (width >= 64rem) { + max-width: 64rem; + } + @media (width >= 80rem) { + max-width: 80rem; + } + @media (width >= 96rem) { + max-width: 96rem; + } + } + + .mx-auto { + margin-inline: auto; + } + + .mt-2 { + margin-top: calc(var(--spacing) * 2); + } + + .mt-4 { + margin-top: calc(var(--spacing) * 4); + } + + .mb-3 { + margin-bottom: calc(var(--spacing) * 3); + } + + .mb-6 { + margin-bottom: calc(var(--spacing) * 6); + } + + .ml-1 { + margin-left: calc(var(--spacing) * 1); + } + + .block { + display: block; + } + + .flex { + display: flex; + } + + .hidden { + display: none; + } + + .inline { + display: inline; + } + + .h-4 { + height: calc(var(--spacing) * 4); + } + + .h-6 { + height: calc(var(--spacing) * 6); + } + + .h-10 { + height: calc(var(--spacing) * 10); + } + + .h-18 { + height: calc(var(--spacing) * 18); + } + + .h-24 { + height: calc(var(--spacing) * 24); + } + + .h-auto { + height: auto; + } + + .h-full { + height: 100%; + } + + .w-3\/4 { + width: calc(3 / 4 * 100%); + } + + .w-4 { + width: calc(var(--spacing) * 4); + } + + .w-6 { + width: calc(var(--spacing) * 6); + } + + .w-10 { + width: calc(var(--spacing) * 10); + } + + .w-18 { + width: calc(var(--spacing) * 18); + } + + .w-24 { + width: calc(var(--spacing) * 24); + } + + .w-48 { + width: calc(var(--spacing) * 48); + } + + .w-full { + width: 100%; + } + + .max-w-7xl { + max-width: var(--container-7xl); + } + + .rotate-180 { rotate: 180deg; - } } - } - .group-hover\:opacity-100 { - &:is(:where(.group):hover *) { - @media (hover: hover) { - opacity: 100%; - } + + .transform { + transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,); } - } - .hover\:bg-gray-100 { - &:hover { - @media (hover: hover) { - background-color: var(--color-gray-100); - } + + .resize { + resize: both; } - } - .hover\:text-blue-600 { - &:hover { - @media (hover: hover) { - color: var(--color-blue-600); - } + + .flex-col { + flex-direction: column; } - } - .hover\:text-pink-500 { - &:hover { - @media (hover: hover) { - color: var(--color-pink-500); - } + + .items-baseline { + align-items: baseline; } - } - .hover\:text-sf_blau-500 { - &:hover { - @media (hover: hover) { + + .items-center { + align-items: center; + } + + .justify-between { + justify-content: space-between; + } + + .justify-center { + justify-content: center; + } + + .gap-6 { + gap: calc(var(--spacing) * 6); + } + + .gap-8 { + gap: calc(var(--spacing) * 8); + } + + .space-y-1 { + :where(& > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse))); + } + } + + .space-x-3 { + :where(& > :not(:last-child)) { + --tw-space-x-reverse: 0; + margin-inline-start: calc(calc(var(--spacing) * 3) * var(--tw-space-x-reverse)); + margin-inline-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-x-reverse))); + } + } + + .space-x-4 { + :where(& > :not(:last-child)) { + --tw-space-x-reverse: 0; + margin-inline-start: calc(calc(var(--spacing) * 4) * var(--tw-space-x-reverse)); + margin-inline-end: calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-x-reverse))); + } + } + + .overflow-hidden { + overflow: hidden; + } + + .rounded-lg { + border-radius: var(--radius-lg); + } + + .rounded-md { + border-radius: var(--radius-md); + } + + .border { + border-style: var(--tw-border-style); + border-width: 1px; + } + + .border-t { + border-top-style: var(--tw-border-style); + border-top-width: 1px; + } + + .border-gray-700 { + border-color: var(--color-gray-700); + } + + .bg-blue-500\/40 { + background-color: color-mix(in srgb, oklch(62.3% 0.214 259.815) 40%, transparent); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-blue-500) 40%, transparent); + } + } + + .bg-sf_grau-50 { + background-color: var(--color-sf_grau-50); + } + + .bg-sf_grau-400 { + background-color: var(--color-sf_grau-400); + } + + .bg-white { + background-color: var(--color-white); + } + + .object-cover { + object-fit: cover; + } + + .px-2 { + padding-inline: calc(var(--spacing) * 2); + } + + .px-3 { + padding-inline: calc(var(--spacing) * 3); + } + + .px-4 { + padding-inline: calc(var(--spacing) * 4); + } + + .py-1 { + padding-block: calc(var(--spacing) * 1); + } + + .py-2 { + padding-block: calc(var(--spacing) * 2); + } + + .py-7 { + padding-block: calc(var(--spacing) * 7); + } + + .py-16 { + padding-block: calc(var(--spacing) * 16); + } + + .py-24 { + padding-block: calc(var(--spacing) * 24); + } + + .pt-2 { + padding-top: calc(var(--spacing) * 2); + } + + .pt-4 { + padding-top: calc(var(--spacing) * 4); + } + + .pb-3 { + padding-bottom: calc(var(--spacing) * 3); + } + + .pl-6 { + padding-left: calc(var(--spacing) * 6); + } + + .text-center { + text-align: center; + } + + .text-left { + text-align: left; + } + + .font-sans { + font-family: var(--font-sans); + } + + .text-4xl { + font-size: var(--text-4xl); + line-height: var(--tw-leading, var(--text-4xl--line-height)); + } + + .text-base { + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + } + + .text-lg { + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); + } + + .text-sm { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + } + + .font-bold { + --tw-font-weight: var(--font-weight-bold); + font-weight: var(--font-weight-bold); + } + + .font-medium { + --tw-font-weight: var(--font-weight-medium); + font-weight: var(--font-weight-medium); + } + + .text-gray-500 { + color: var(--color-gray-500); + } + + .text-gray-600 { + color: var(--color-gray-600); + } + + .text-gray-700 { + color: var(--color-gray-700); + } + + .text-gray-900 { + color: var(--color-gray-900); + } + + .text-sf_blau-500 { color: var(--color-sf_blau-500); - } } - } - .hover\:text-sf_blau-700 { - &:hover { - @media (hover: hover) { - color: var(--color-sf_blau-700); - } + + .text-sf_grau-600 { + color: var(--color-sf_grau-600); } - } - .hover\:text-sf_gelb-500 { - &:hover { - @media (hover: hover) { - color: var(--color-sf_gelb-500); - } + + .text-sf_grau-800 { + color: var(--color-sf_grau-800); } - } - .focus\:text-blue-600 { - &:focus { - color: var(--color-blue-600); + + .text-white { + color: var(--color-white); } - } - .focus\:outline-none { - &:focus { - --tw-outline-style: none; - outline-style: none; + + .antialiased { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } - } - .sm\:flex { - @media (width >= 40rem) { - display: flex; + + .opacity-0 { + opacity: 0%; } - } - .sm\:px-3 { - @media (width >= 40rem) { - padding-inline: calc(var(--spacing) * 3); + + .opacity-50 { + opacity: 50%; } - } - .sm\:px-6 { - @media (width >= 40rem) { - padding-inline: calc(var(--spacing) * 6); + + .shadow-lg { + --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } - } - .md\:top-6 { - @media (width >= 48rem) { - top: calc(var(--spacing) * 6); + + .shadow-xl { + --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } - } - .md\:block { - @media (width >= 48rem) { - display: block; + + .transition-all { + transition-property: all; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); } - } - .md\:hidden { - @media (width >= 48rem) { - display: none; + + .transition-colors { + transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); } - } - .md\:h-36 { - @media (width >= 48rem) { - height: calc(var(--spacing) * 36); + + .transition-transform { + transition-property: transform, translate, scale, rotate; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); } - } - .md\:w-1\/2 { - @media (width >= 48rem) { - width: calc(1/2 * 100%); + + .duration-200 { + --tw-duration: 200ms; + transition-duration: 200ms; } - } - .md\:w-36 { - @media (width >= 48rem) { - width: calc(var(--spacing) * 36); + + .duration-500 { + --tw-duration: 500ms; + transition-duration: 500ms; } - } - .md\:py-32 { - @media (width >= 48rem) { - padding-block: calc(var(--spacing) * 32); + + .group-hover\:visible { + &:is(:where(.group):hover *) { + @media (hover: hover) { + visibility: visible; + } + } } - } - .lg\:flex { - @media (width >= 64rem) { - display: flex; + + .group-hover\:rotate-180 { + &:is(:where(.group):hover *) { + @media (hover: hover) { + rotate: 180deg; + } + } } - } - .lg\:w-1\/2 { - @media (width >= 64rem) { - width: calc(1/2 * 100%); + + .group-hover\:opacity-100 { + &:is(:where(.group):hover *) { + @media (hover: hover) { + opacity: 100%; + } + } } - } - .lg\:flex-row { - @media (width >= 64rem) { - flex-direction: row; + + .hover\:bg-gray-100 { + &:hover { + @media (hover: hover) { + background-color: var(--color-gray-100); + } + } } - } - .lg\:gap-10 { - @media (width >= 64rem) { - gap: calc(var(--spacing) * 10); + + .hover\:text-blue-600 { + &:hover { + @media (hover: hover) { + color: var(--color-blue-600); + } + } } - } - .lg\:gap-16 { - @media (width >= 64rem) { - gap: calc(var(--spacing) * 16); + + .hover\:text-pink-500 { + &:hover { + @media (hover: hover) { + color: var(--color-pink-500); + } + } } - } - .lg\:px-8 { - @media (width >= 64rem) { - padding-inline: calc(var(--spacing) * 8); + + .hover\:text-sf_blau-500 { + &:hover { + @media (hover: hover) { + color: var(--color-sf_blau-500); + } + } } - } - .xl\:gap-14 { - @media (width >= 80rem) { - gap: calc(var(--spacing) * 14); + + .hover\:text-sf_blau-700 { + &:hover { + @media (hover: hover) { + color: var(--color-sf_blau-700); + } + } + } + + .hover\:text-sf_gelb-500 { + &:hover { + @media (hover: hover) { + color: var(--color-sf_gelb-500); + } + } + } + + .focus\:text-blue-600 { + &:focus { + color: var(--color-blue-600); + } + } + + .focus\:outline-none { + &:focus { + --tw-outline-style: none; + outline-style: none; + } + } + + .sm\:flex { + @media (width >= 40rem) { + display: flex; + } + } + + .sm\:px-3 { + @media (width >= 40rem) { + padding-inline: calc(var(--spacing) * 3); + } + } + + .sm\:px-6 { + @media (width >= 40rem) { + padding-inline: calc(var(--spacing) * 6); + } + } + + .md\:top-6 { + @media (width >= 48rem) { + top: calc(var(--spacing) * 6); + } + } + + .md\:block { + @media (width >= 48rem) { + display: block; + } + } + + .md\:hidden { + @media (width >= 48rem) { + display: none; + } + } + + .md\:h-36 { + @media (width >= 48rem) { + height: calc(var(--spacing) * 36); + } + } + + .md\:w-1\/2 { + @media (width >= 48rem) { + width: calc(1 / 2 * 100%); + } + } + + .md\:w-36 { + @media (width >= 48rem) { + width: calc(var(--spacing) * 36); + } + } + + .md\:py-32 { + @media (width >= 48rem) { + padding-block: calc(var(--spacing) * 32); + } + } + + .lg\:flex { + @media (width >= 64rem) { + display: flex; + } + } + + .lg\:w-1\/2 { + @media (width >= 64rem) { + width: calc(1 / 2 * 100%); + } + } + + .lg\:flex-row { + @media (width >= 64rem) { + flex-direction: row; + } + } + + .lg\:gap-10 { + @media (width >= 64rem) { + gap: calc(var(--spacing) * 10); + } + } + + .lg\:gap-16 { + @media (width >= 64rem) { + gap: calc(var(--spacing) * 16); + } + } + + .lg\:px-8 { + @media (width >= 64rem) { + padding-inline: calc(var(--spacing) * 8); + } + } + + .xl\:gap-14 { + @media (width >= 80rem) { + gap: calc(var(--spacing) * 14); + } } - } } + @property --tw-rotate-x { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @property --tw-rotate-y { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @property --tw-rotate-z { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @property --tw-skew-x { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @property --tw-skew-y { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @property --tw-space-y-reverse { - syntax: "*"; - inherits: false; - initial-value: 0; + syntax: "*"; + inherits: false; + initial-value: 0; } + @property --tw-space-x-reverse { - syntax: "*"; - inherits: false; - initial-value: 0; + syntax: "*"; + inherits: false; + initial-value: 0; } + @property --tw-border-style { - syntax: "*"; - inherits: false; - initial-value: solid; + syntax: "*"; + inherits: false; + initial-value: solid; } + @property --tw-font-weight { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @property --tw-shadow { - syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; } + @property --tw-shadow-color { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @property --tw-shadow-alpha { - syntax: ""; - inherits: false; - initial-value: 100%; + syntax: ""; + inherits: false; + initial-value: 100%; } + @property --tw-inset-shadow { - syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; } + @property --tw-inset-shadow-color { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @property --tw-inset-shadow-alpha { - syntax: ""; - inherits: false; - initial-value: 100%; + syntax: ""; + inherits: false; + initial-value: 100%; } + @property --tw-ring-color { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @property --tw-ring-shadow { - syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; } + @property --tw-inset-ring-color { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @property --tw-inset-ring-shadow { - syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; } + @property --tw-ring-inset { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @property --tw-ring-offset-width { - syntax: ""; - inherits: false; - initial-value: 0px; + syntax: ""; + inherits: false; + initial-value: 0px; } + @property --tw-ring-offset-color { - syntax: "*"; - inherits: false; - initial-value: #fff; + syntax: "*"; + inherits: false; + initial-value: #fff; } + @property --tw-ring-offset-shadow { - syntax: "*"; - inherits: false; - initial-value: 0 0 #0000; + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; } + @property --tw-duration { - syntax: "*"; - inherits: false; + syntax: "*"; + inherits: false; } + @layer properties { - @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) { - *, ::before, ::after, ::backdrop { - --tw-rotate-x: initial; - --tw-rotate-y: initial; - --tw-rotate-z: initial; - --tw-skew-x: initial; - --tw-skew-y: initial; - --tw-space-y-reverse: 0; - --tw-space-x-reverse: 0; - --tw-border-style: solid; - --tw-font-weight: initial; - --tw-shadow: 0 0 #0000; - --tw-shadow-color: initial; - --tw-shadow-alpha: 100%; - --tw-inset-shadow: 0 0 #0000; - --tw-inset-shadow-color: initial; - --tw-inset-shadow-alpha: 100%; - --tw-ring-color: initial; - --tw-ring-shadow: 0 0 #0000; - --tw-inset-ring-color: initial; - --tw-inset-ring-shadow: 0 0 #0000; - --tw-ring-inset: initial; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-offset-shadow: 0 0 #0000; - --tw-duration: initial; + @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) { + *, ::before, ::after, ::backdrop { + --tw-rotate-x: initial; + --tw-rotate-y: initial; + --tw-rotate-z: initial; + --tw-skew-x: initial; + --tw-skew-y: initial; + --tw-space-y-reverse: 0; + --tw-space-x-reverse: 0; + --tw-border-style: solid; + --tw-font-weight: initial; + --tw-shadow: 0 0 #0000; + --tw-shadow-color: initial; + --tw-shadow-alpha: 100%; + --tw-inset-shadow: 0 0 #0000; + --tw-inset-shadow-color: initial; + --tw-inset-shadow-alpha: 100%; + --tw-ring-color: initial; + --tw-ring-shadow: 0 0 #0000; + --tw-inset-ring-color: initial; + --tw-inset-ring-shadow: 0 0 #0000; + --tw-ring-inset: initial; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-offset-shadow: 0 0 #0000; + --tw-duration: initial; + } } - } } diff --git a/assets/fonts/pgn4web-font-ChessSansUsual.css b/assets/fonts/pgn4web-font-ChessSansUsual.css index 70d7868..d13e4fe 100644 --- a/assets/fonts/pgn4web-font-ChessSansUsual.css +++ b/assets/fonts/pgn4web-font-ChessSansUsual.css @@ -14,8 +14,8 @@ */ @font-face { - font-family: 'pgn4web ChessSansUsual'; - src: url('ChessSansUsual.eot'); - src: url('ChessSansUsual.eot?#iefix') format('embedded-opentype'), url('ChessSansUsual.woff') format('woff'), url('ChessSansUsual.ttf') format('truetype'), url('ChessSansUsual.svg#ChessSansUsual') format('svg'); + font-family: 'pgn4web ChessSansUsual'; + src: url('ChessSansUsual.eot'); + src: url('ChessSansUsual.eot?#iefix') format('embedded-opentype'), url('ChessSansUsual.woff') format('woff'), url('ChessSansUsual.ttf') format('truetype'), url('ChessSansUsual.svg#ChessSansUsual') format('svg'); } diff --git a/assets/fonts/pgn4web-font-LiberationSans.css b/assets/fonts/pgn4web-font-LiberationSans.css index 0e2048a..dd18e42 100644 --- a/assets/fonts/pgn4web-font-LiberationSans.css +++ b/assets/fonts/pgn4web-font-LiberationSans.css @@ -11,16 +11,16 @@ */ @font-face { - font-family: 'pgn4web Liberation Sans'; - src: url('LiberationSans-Regular.eot'); - src: url('LiberationSans-Regular.eot?#iefix') format('embedded-opentype'), url('LiberationSans-Regular.woff') format('woff'), url('LiberationSans-Regular.ttf') format('truetype'), url('LiberationSans-Regular.svg#LiberationSans') format('svg'); - font-weight: normal; + font-family: 'pgn4web Liberation Sans'; + src: url('LiberationSans-Regular.eot'); + src: url('LiberationSans-Regular.eot?#iefix') format('embedded-opentype'), url('LiberationSans-Regular.woff') format('woff'), url('LiberationSans-Regular.ttf') format('truetype'), url('LiberationSans-Regular.svg#LiberationSans') format('svg'); + font-weight: normal; } @font-face { - font-family: 'pgn4web Liberation Sans'; - src: url('LiberationSans-Bold.eot'); - src: url('LiberationSans-Bold.eot?#iefix') format('embedded-opentype'), url('LiberationSans-Bold.woff') format('woff'), url('LiberationSans-Bold.ttf') format('truetype'), url('LiberationSans-Bold.svg#LiberationSans-Bold') format('svg'); - font-weight: bold; + font-family: 'pgn4web Liberation Sans'; + src: url('LiberationSans-Bold.eot'); + src: url('LiberationSans-Bold.eot?#iefix') format('embedded-opentype'), url('LiberationSans-Bold.woff') format('woff'), url('LiberationSans-Bold.ttf') format('truetype'), url('LiberationSans-Bold.svg#LiberationSans-Bold') format('svg'); + font-weight: bold; } diff --git a/assets/js/png4web.js b/assets/js/png4web.js index 6e87e23..1b6a564 100644 --- a/assets/js/png4web.js +++ b/assets/js/png4web.js @@ -14,51 +14,82 @@ var pgn4web_project_author = "Paolo Casaschi"; var pgn4web_project_email = "pgn4web@casaschi.net"; var helpWin; + function displayHelp(section) { - if (helpWin && !helpWin.closed) { helpWin.close(); } - helpWin = window.open(detectHelpLocation() + (section ? "?" + section : ""), "pgn4web_help", "resizable=yes,scrollbars=yes,toolbar=no,location=no,menubar=no,status=no"); - if (helpWin && window.focus) { helpWin.focus(); } + if (helpWin && !helpWin.closed) { + helpWin.close(); + } + helpWin = window.open(detectHelpLocation() + (section ? "?" + section : ""), "pgn4web_help", "resizable=yes,scrollbars=yes,toolbar=no,location=no,menubar=no,status=no"); + if (helpWin && window.focus) { + helpWin.focus(); + } } // empty event APIs to be redefined -function customFunctionOnPgnTextLoad() {} -function customFunctionOnPgnGameLoad() {} -function customFunctionOnMove() {} -function customFunctionOnAlert(msg) {} -function customFunctionOnCheckLiveBroadcastStatus() {} +function customFunctionOnPgnTextLoad() { +} + +function customFunctionOnPgnGameLoad() { +} + +function customFunctionOnMove() { +} + +function customFunctionOnAlert(msg) { +} + +function customFunctionOnCheckLiveBroadcastStatus() { +} // custom header tags APIs for customFunctionOnPgnGameLoad function customPgnHeaderTag(customTag, htmlElementId, gameNum) { - var matches, tag = ""; - customTag = customTag.replace(/\W+/g, ""); - if (gameNum === undefined) { gameNum = currentGame; } - if ((pgnHeader[gameNum]) && (matches = pgnHeader[gameNum].match('\\[\\s*' + customTag + '\\s*\"([^\"]+)\"\\s*\\]'))) { tag = matches[1]; } - if (htmlElementId) { - var theObj = document.getElementById(htmlElementId); - if ((theObj) && (typeof(theObj.innerHTML) == "string")) { theObj.innerHTML = tag; } - } - return tag; + var matches, tag = ""; + customTag = customTag.replace(/\W+/g, ""); + if (gameNum === undefined) { + gameNum = currentGame; + } + if ((pgnHeader[gameNum]) && (matches = pgnHeader[gameNum].match('\\[\\s*' + customTag + '\\s*\"([^\"]+)\"\\s*\\]'))) { + tag = matches[1]; + } + if (htmlElementId) { + var theObj = document.getElementById(htmlElementId); + if ((theObj) && (typeof (theObj.innerHTML) == "string")) { + theObj.innerHTML = tag; + } + } + return tag; } // custom comment tags API for customFunctionOnMove function customPgnCommentTag(customTag, htmlElementId, plyNum, varId) { - var matches, tag = "", theObj; - customTag = customTag.replace(/\W+/g, ""); - if (typeof(varId) == "undefined") { varId = 0; } - if (typeof(plyNum) == "undefined") { plyNum = CurrentPly; } - if ((MoveCommentsVar[varId][plyNum]) && (matches = MoveCommentsVar[varId][plyNum].match('\\[%' + customTag + '\\s+((?:,?(?:"[^"]*"|[^,\\]]*))*)\\s*\\]'))) { tag = matches[1].replace(/\s+$/, ""); } - if ((htmlElementId) && (theObj = document.getElementById(htmlElementId)) && (typeof(theObj.innerHTML) == "string")) { theObj.innerHTML = tag; } - return tag; + var matches, tag = "", theObj; + customTag = customTag.replace(/\W+/g, ""); + if (typeof (varId) == "undefined") { + varId = 0; + } + if (typeof (plyNum) == "undefined") { + plyNum = CurrentPly; + } + if ((MoveCommentsVar[varId][plyNum]) && (matches = MoveCommentsVar[varId][plyNum].match('\\[%' + customTag + '\\s+((?:,?(?:"[^"]*"|[^,\\]]*))*)\\s*\\]'))) { + tag = matches[1].replace(/\s+$/, ""); + } + if ((htmlElementId) && (theObj = document.getElementById(htmlElementId)) && (typeof (theObj.innerHTML) == "string")) { + theObj.innerHTML = tag; + } + return tag; } function simpleAddEvent(obj, evt, cbk) { - if (obj.addEventListener) { obj.addEventListener(evt, cbk, false); } - else if (obj.attachEvent) { obj.attachEvent("on" + evt, cbk); } // bugfix: IE8 and below specific + if (obj.addEventListener) { + obj.addEventListener(evt, cbk, false); + } else if (obj.attachEvent) { + obj.attachEvent("on" + evt, cbk); + } // bugfix: IE8 and below specific } simpleAddEvent(document, "keydown", pgn4web_handleKey_event); @@ -66,20 +97,23 @@ simpleAddEvent(window, "load", pgn4web_onload_event); function pgn4web_onload_event(e) { - pgn4web_onload(e); + pgn4web_onload(e); } function pgn4web_onload(e) { - start_pgn4web(); + start_pgn4web(); } function start_pgn4web() { - // keep startup logs at the very first run, otherwise reset - if (alertFirstResetLoadingPgn) { alertFirstResetLoadingPgn = false; } - else { resetAlert(); } - InitImages(); - createBoard(); - pgn4web_initTouchEvents(); + // keep startup logs at the very first run, otherwise reset + if (alertFirstResetLoadingPgn) { + alertFirstResetLoadingPgn = false; + } else { + resetAlert(); + } + InitImages(); + createBoard(); + pgn4web_initTouchEvents(); } var alertLog; @@ -94,384 +128,529 @@ var alertFirstResetLoadingPgn = true; resetAlert(); function resetAlert() { - alertLog = new Array(5); - alertLast = alertLog.length - 1; - alertNum = alertNumSinceReset = fatalErrorNumSinceReset = 0; - stopAlertPrompt(); - if (!alertFirstResetLoadingPgn) { - if (boardIsDefault(debugShortcutSquare)) { boardShortcut(debugShortcutSquare, "pgn4web v" + pgn4web_version + " debug info", null, true); } - } + alertLog = new Array(5); + alertLast = alertLog.length - 1; + alertNum = alertNumSinceReset = fatalErrorNumSinceReset = 0; + stopAlertPrompt(); + if (!alertFirstResetLoadingPgn) { + if (boardIsDefault(debugShortcutSquare)) { + boardShortcut(debugShortcutSquare, "pgn4web v" + pgn4web_version + " debug info", null, true); + } + } } function myAlert(msg, fatalError, doNotPrompt) { - alertNum++; - alertNumSinceReset++; - if (fatalError) { fatalErrorNumSinceReset++; } - alertLast = (alertLast + 1) % alertLog.length; - alertLog[alertLast] = msg + "\n" + (new Date()).toLocaleString(); - if (boardIsDefault(debugShortcutSquare)) { boardShortcut(debugShortcutSquare, "pgn4web v" + pgn4web_version + " debug info\n" + alertNum + " alert" + (alertNum > 1 ? "s" : ""), null, true); } - if ((!doNotPrompt) && ((LiveBroadcastDelay === 0) || (LiveBroadcastAlert === true)) && (boardIsDefault(debugShortcutSquare))) { startAlertPrompt(); } - customFunctionOnAlert(msg); + alertNum++; + alertNumSinceReset++; + if (fatalError) { + fatalErrorNumSinceReset++; + } + alertLast = (alertLast + 1) % alertLog.length; + alertLog[alertLast] = msg + "\n" + (new Date()).toLocaleString(); + if (boardIsDefault(debugShortcutSquare)) { + boardShortcut(debugShortcutSquare, "pgn4web v" + pgn4web_version + " debug info\n" + alertNum + " alert" + (alertNum > 1 ? "s" : ""), null, true); + } + if ((!doNotPrompt) && ((LiveBroadcastDelay === 0) || (LiveBroadcastAlert === true)) && (boardIsDefault(debugShortcutSquare))) { + startAlertPrompt(); + } + customFunctionOnAlert(msg); } function startAlertPrompt() { - if (alertPromptOn) { return; } // dont start flashing twice - if (alertPromptInterval) { clearTimeout(alertPromptInterval); } - alertPromptInterval = setTimeout("alertPromptTick(true);", 500); + if (alertPromptOn) { + return; + } // dont start flashing twice + if (alertPromptInterval) { + clearTimeout(alertPromptInterval); + } + alertPromptInterval = setTimeout("alertPromptTick(true);", 500); } function stopAlertPrompt() { - if (alertPromptInterval) { - clearTimeout(alertPromptInterval); - alertPromptInterval = null; - } - if (alertPromptOn) { alertPromptTick(false); } + if (alertPromptInterval) { + clearTimeout(alertPromptInterval); + alertPromptInterval = null; + } + if (alertPromptOn) { + alertPromptTick(false); + } } function alertPromptTick(restart) { - if (alertPromptInterval) { - clearTimeout(alertPromptInterval); - alertPromptInterval = null; - } - var colRow = colRowFromSquare(debugShortcutSquare); - if (!colRow) { return; } + if (alertPromptInterval) { + clearTimeout(alertPromptInterval); + alertPromptInterval = null; + } + var colRow = colRowFromSquare(debugShortcutSquare); + if (!colRow) { + return; + } - var alertPromptDelay = 1500; // for alerts before the board is printed - var theObj = document.getElementById('tcol' + colRow.col + 'trow' + colRow.row); - if (theObj) { - if (alertPromptOn) { - if ((highlightOption) && ((colFromHighlighted === 0 && rowFromHighlighted === 7) || (colToHighlighted === 0 && rowToHighlighted === 7))) { - theObj.className = 'highlightWhiteSquare'; - } else { theObj.className = 'whiteSquare'; } - } else { theObj.className = 'blackSquare'; } + var alertPromptDelay = 1500; // for alerts before the board is printed + var theObj = document.getElementById('tcol' + colRow.col + 'trow' + colRow.row); + if (theObj) { + if (alertPromptOn) { + if ((highlightOption) && ((colFromHighlighted === 0 && rowFromHighlighted === 7) || (colToHighlighted === 0 && rowToHighlighted === 7))) { + theObj.className = 'highlightWhiteSquare'; + } else { + theObj.className = 'whiteSquare'; + } + } else { + theObj.className = 'blackSquare'; + } - alertPromptOn = !alertPromptOn; - if (alertPromptOn) { alertPromptDelay = 500; } - else { alertPromptDelay = 3000; } - } - if (restart) { alertPromptInterval = setTimeout("alertPromptTick(true);", alertPromptDelay); } + alertPromptOn = !alertPromptOn; + if (alertPromptOn) { + alertPromptDelay = 500; + } else { + alertPromptDelay = 3000; + } + } + if (restart) { + alertPromptInterval = setTimeout("alertPromptTick(true);", alertPromptDelay); + } } function stopEvProp(e) { - e.cancelBubble = true; - if (e.stopPropagation) { e.stopPropagation(); } - if (e.preventDefault) { e.preventDefault(); } - return false; + e.cancelBubble = true; + if (e.stopPropagation) { + e.stopPropagation(); + } + if (e.preventDefault) { + e.preventDefault(); + } + return false; } // for onFocus/onBlur textbox events, allowing text typing var shortcutKeysWereEnabled = false; + function disableShortcutKeysAndStoreStatus() { - if ((shortcutKeysWereEnabled = shortcutKeysEnabled) === true) { - SetShortcutKeysEnabled(false); - } -} -function restoreShortcutKeysStatus() { - if (shortcutKeysWereEnabled === true) { SetShortcutKeysEnabled(true); } - shortcutKeysWereEnabled = false; + if ((shortcutKeysWereEnabled = shortcutKeysEnabled) === true) { + SetShortcutKeysEnabled(false); + } } -function customShortcutKey_Shift_0() {} -function customShortcutKey_Shift_1() {} -function customShortcutKey_Shift_2() {} -function customShortcutKey_Shift_3() {} -function customShortcutKey_Shift_4() {} -function customShortcutKey_Shift_5() {} -function customShortcutKey_Shift_6() {} -function customShortcutKey_Shift_7() {} -function customShortcutKey_Shift_8() {} -function customShortcutKey_Shift_9() {} +function restoreShortcutKeysStatus() { + if (shortcutKeysWereEnabled === true) { + SetShortcutKeysEnabled(true); + } + shortcutKeysWereEnabled = false; +} + +function customShortcutKey_Shift_0() { +} + +function customShortcutKey_Shift_1() { +} + +function customShortcutKey_Shift_2() { +} + +function customShortcutKey_Shift_3() { +} + +function customShortcutKey_Shift_4() { +} + +function customShortcutKey_Shift_5() { +} + +function customShortcutKey_Shift_6() { +} + +function customShortcutKey_Shift_7() { +} + +function customShortcutKey_Shift_8() { +} + +function customShortcutKey_Shift_9() { +} function pgn4web_handleKey_event(e) { - pgn4web_handleKey(e); + pgn4web_handleKey(e); } var shortcutKeysEnabled = false; + function pgn4web_handleKey(e) { - var keycode, oldPly, oldVar, colRow, colRowList; + var keycode, oldPly, oldVar, colRow, colRowList; - if (!e) { e = window.event; } + if (!e) { + e = window.event; + } - if (e.altKey || e.ctrlKey || e.metaKey) { return true; } + if (e.altKey || e.ctrlKey || e.metaKey) { + return true; + } - keycode = e.keyCode; + keycode = e.keyCode; - // shift-escape always enabled: toggle shortcut keys - if (!shortcutKeysEnabled && !(keycode == 27 && e.shiftKey)) { return true; } + // shift-escape always enabled: toggle shortcut keys + if (!shortcutKeysEnabled && !(keycode == 27 && e.shiftKey)) { + return true; + } - switch (keycode) { + switch (keycode) { - case 8: // backspace - case 9: // tab - case 16: // shift - case 17: // ctrl - case 18: // alt - case 32: // space - case 33: // page-up - case 34: // page-down - case 35: // end - case 36: // home - case 92: // super - case 93: // menu - case 188: // comma - return true; + case 8: // backspace + case 9: // tab + case 16: // shift + case 17: // ctrl + case 18: // alt + case 32: // space + case 33: // page-up + case 34: // page-down + case 35: // end + case 36: // home + case 92: // super + case 93: // menu + case 188: // comma + return true; - case 27: // escape - if (e.shiftKey) { interactivelyToggleShortcutKeys(); } - else { displayHelp(); } - break; + case 27: // escape + if (e.shiftKey) { + interactivelyToggleShortcutKeys(); + } else { + displayHelp(); + } + break; - case 189: // dash - if (colRowList = prompt("Enter shortcut square coordinates to click:", "")) { - colRowList = colRowList.toUpperCase().replace(/[^A-Z0-9]/g,""); - while (colRow = colRowFromSquare(colRowList)) { - boardOnClick[colRow.col][colRow.row]({"id": "img_tcol" + colRow.col + "trow" + colRow.row}, e); - colRowList = colRowList.substr(2); - } - } - break; + case 189: // dash + if (colRowList = prompt("Enter shortcut square coordinates to click:", "")) { + colRowList = colRowList.toUpperCase().replace(/[^A-Z0-9]/g, ""); + while (colRow = colRowFromSquare(colRowList)) { + boardOnClick[colRow.col][colRow.row]({"id": "img_tcol" + colRow.col + "trow" + colRow.row}, e); + colRowList = colRowList.substr(2); + } + } + break; - case 90: // z - if (e.shiftKey) { window.open(pgn4web_project_url); } - else { displayDebugInfo(); } - break; + case 90: // z + if (e.shiftKey) { + window.open(pgn4web_project_url); + } else { + displayDebugInfo(); + } + break; - case 37: // left-arrow - case 74: // j - backButton(e); - break; + case 37: // left-arrow + case 74: // j + backButton(e); + break; - case 38: // up-arrow - case 72: // h - startButton(e); - break; + case 38: // up-arrow + case 72: // h + startButton(e); + break; - case 39: // right-arrow - case 75: // k - forwardButton(e); - break; + case 39: // right-arrow + case 75: // k + forwardButton(e); + break; - case 40: // down-arrow - case 76: // l - endButton(e); - break; + case 40: // down-arrow + case 76: // l + endButton(e); + break; - case 73: // i - MoveToPrevComment(e.shiftKey); - break; + case 73: // i + MoveToPrevComment(e.shiftKey); + break; - case 79: // o - MoveToNextComment(e.shiftKey); - break; + case 79: // o + MoveToNextComment(e.shiftKey); + break; - case 190: // dot - if (e.shiftKey) { goToFirstChild(); } - else { goToNextVariationSibling(); } - break; + case 190: // dot + if (e.shiftKey) { + goToFirstChild(); + } else { + goToNextVariationSibling(); + } + break; - case 85: // u - if (e.shiftKey) { undoStackRedo(); } - else { undoStackUndo(); } - break; + case 85: // u + if (e.shiftKey) { + undoStackRedo(); + } else { + undoStackUndo(); + } + break; - case 45: // insert - undoStackRedo(); - break; + case 45: // insert + undoStackRedo(); + break; - case 46: // delete - undoStackUndo(); - break; + case 46: // delete + undoStackUndo(); + break; - case 83: // s - if (e.shiftKey) { searchPgnGame(""); } - else { searchPgnGamePrompt(); } - break; + case 83: // s + if (e.shiftKey) { + searchPgnGame(""); + } else { + searchPgnGamePrompt(); + } + break; - case 13: // enter - if (e.shiftKey) { searchPgnGame(lastSearchPgnExpression, true); } - else { searchPgnGame(lastSearchPgnExpression); } - break; + case 13: // enter + if (e.shiftKey) { + searchPgnGame(lastSearchPgnExpression, true); + } else { + searchPgnGame(lastSearchPgnExpression); + } + break; - case 68: // d - if (e.shiftKey) { displayFenData(); } - else { displayPgnData(true); } - break; + case 68: // d + if (e.shiftKey) { + displayFenData(); + } else { + displayPgnData(true); + } + break; - case 187: // equal - SwitchAutoPlay(); - break; + case 187: // equal + SwitchAutoPlay(); + break; - case 65: // a - GoToMove(CurrentPly + 1); - SetAutoPlay(true); - break; + case 65: // a + GoToMove(CurrentPly + 1); + SetAutoPlay(true); + break; - case 48: // 0 - if (e.shiftKey) { customShortcutKey_Shift_0(); } - else { SetAutoPlay(false); } - break; + case 48: // 0 + if (e.shiftKey) { + customShortcutKey_Shift_0(); + } else { + SetAutoPlay(false); + } + break; - case 49: // 1 - if (e.shiftKey) { customShortcutKey_Shift_1(); } - else { SetAutoplayDelayAndStart( 1*1000); } - break; + case 49: // 1 + if (e.shiftKey) { + customShortcutKey_Shift_1(); + } else { + SetAutoplayDelayAndStart(1 * 1000); + } + break; - case 50: // 2 - if (e.shiftKey) { customShortcutKey_Shift_2(); } - else { SetAutoplayDelayAndStart( 2*1000); } - break; + case 50: // 2 + if (e.shiftKey) { + customShortcutKey_Shift_2(); + } else { + SetAutoplayDelayAndStart(2 * 1000); + } + break; - case 51: // 3 - if (e.shiftKey) { customShortcutKey_Shift_3(); } - else { SetAutoplayDelayAndStart( 3*1000); } - break; + case 51: // 3 + if (e.shiftKey) { + customShortcutKey_Shift_3(); + } else { + SetAutoplayDelayAndStart(3 * 1000); + } + break; - case 52: // 4 - if (e.shiftKey) { customShortcutKey_Shift_4(); } - else { SetAutoplayDelayAndStart( 4*1000); } - break; + case 52: // 4 + if (e.shiftKey) { + customShortcutKey_Shift_4(); + } else { + SetAutoplayDelayAndStart(4 * 1000); + } + break; - case 53: // 5 - if (e.shiftKey) { customShortcutKey_Shift_5(); } - else { SetAutoplayDelayAndStart( 5*1000); } - break; + case 53: // 5 + if (e.shiftKey) { + customShortcutKey_Shift_5(); + } else { + SetAutoplayDelayAndStart(5 * 1000); + } + break; - case 54: // 6 - if (e.shiftKey) { customShortcutKey_Shift_6(); } - else { SetAutoplayDelayAndStart( 6*1000); } - break; + case 54: // 6 + if (e.shiftKey) { + customShortcutKey_Shift_6(); + } else { + SetAutoplayDelayAndStart(6 * 1000); + } + break; - case 55: // 7 - if (e.shiftKey) { customShortcutKey_Shift_7(); } - else { SetAutoplayDelayAndStart( 7*1000); } - break; + case 55: // 7 + if (e.shiftKey) { + customShortcutKey_Shift_7(); + } else { + SetAutoplayDelayAndStart(7 * 1000); + } + break; - case 56: // 8 - if (e.shiftKey) { customShortcutKey_Shift_8(); } - else { SetAutoplayDelayAndStart( 8*1000); } - break; + case 56: // 8 + if (e.shiftKey) { + customShortcutKey_Shift_8(); + } else { + SetAutoplayDelayAndStart(8 * 1000); + } + break; - case 57: // 9 - if (e.shiftKey) { customShortcutKey_Shift_9(); } - else { setCustomAutoplayDelay(); } - break; + case 57: // 9 + if (e.shiftKey) { + customShortcutKey_Shift_9(); + } else { + setCustomAutoplayDelay(); + } + break; - case 81: // q - SetAutoplayDelayAndStart(10*1000); - break; + case 81: // q + SetAutoplayDelayAndStart(10 * 1000); + break; - case 87: // w - SetAutoplayDelayAndStart(20*1000); - break; + case 87: // w + SetAutoplayDelayAndStart(20 * 1000); + break; - case 69: // e - SetAutoplayDelayAndStart(30*1000); - break; + case 69: // e + SetAutoplayDelayAndStart(30 * 1000); + break; - case 82: // r - pauseLiveBroadcast(); - break; + case 82: // r + pauseLiveBroadcast(); + break; - case 84: // t - if (e.shiftKey) { LiveBroadcastSteppingMode = !LiveBroadcastSteppingMode; } - else { refreshPgnSource(); } - break; + case 84: // t + if (e.shiftKey) { + LiveBroadcastSteppingMode = !LiveBroadcastSteppingMode; + } else { + refreshPgnSource(); + } + break; - case 89: // y - restartLiveBroadcast(); - break; + case 89: // y + restartLiveBroadcast(); + break; - case 70: // f - if (!e.shiftKey || IsRotated) { FlipBoard(); } - break; + case 70: // f + if (!e.shiftKey || IsRotated) { + FlipBoard(); + } + break; - case 71: // g - SetHighlight(!highlightOption); - break; + case 71: // g + SetHighlight(!highlightOption); + break; - case 88: // x - randomGameRandomPly(); - break; + case 88: // x + randomGameRandomPly(); + break; - case 67: // c - if (numberOfGames > 1) { Init(Math.floor(Math.random()*numberOfGames)); } - break; + case 67: // c + if (numberOfGames > 1) { + Init(Math.floor(Math.random() * numberOfGames)); + } + break; - case 86: // v - if (numberOfGames > 1) { Init(0); } - break; + case 86: // v + if (numberOfGames > 1) { + Init(0); + } + break; - case 66: // b - Init(currentGame - 1); - break; + case 66: // b + Init(currentGame - 1); + break; - case 78: // n - Init(currentGame + 1); - break; + case 78: // n + Init(currentGame + 1); + break; - case 77: // m - if (numberOfGames > 1) { Init(numberOfGames - 1); } - break; + case 77: // m + if (numberOfGames > 1) { + Init(numberOfGames - 1); + } + break; - case 80: // p - if (e.shiftKey) { SetCommentsOnSeparateLines(!commentsOnSeparateLines); } - else { SetCommentsIntoMoveText(!commentsIntoMoveText); } - oldPly = CurrentPly; - oldVar = CurrentVar; - Init(); - GoToMove(oldPly, oldVar); - break; + case 80: // p + if (e.shiftKey) { + SetCommentsOnSeparateLines(!commentsOnSeparateLines); + } else { + SetCommentsIntoMoveText(!commentsIntoMoveText); + } + oldPly = CurrentPly; + oldVar = CurrentVar; + Init(); + GoToMove(oldPly, oldVar); + break; - default: - return true; - } - return stopEvProp(e); + default: + return true; + } + return stopEvProp(e); } var boardOnClick = new Array(8); var boardTitle = new Array(8); var boardDefault = new Array(8); -for (var col=0; col<8; col++) { - boardOnClick[col] = new Array(8); - boardTitle[col] = new Array(8); - boardDefault[col] = new Array(8); +for (var col = 0; col < 8; col++) { + boardOnClick[col] = new Array(8); + boardTitle[col] = new Array(8); + boardDefault[col] = new Array(8); } clearShortcutSquares("ABCDEFGH", "12345678"); function colRowFromSquare(square) { - if ((typeof(square) != "string") || (!square)) { return null; } - var col = square.charCodeAt(0) - 65; // 65="A" - if ((col < 0) || (col > 7)) { return null; } - var row = 56 - square.charCodeAt(1); // 56="8" - if ((row < 0) || (row > 7)) { return null; } - return { "col": col, "row": row }; + if ((typeof (square) != "string") || (!square)) { + return null; + } + var col = square.charCodeAt(0) - 65; // 65="A" + if ((col < 0) || (col > 7)) { + return null; + } + var row = 56 - square.charCodeAt(1); // 56="8" + if ((row < 0) || (row > 7)) { + return null; + } + return {"col": col, "row": row}; } function clearShortcutSquares(cols, rows) { - if ((typeof(cols) != "string") || (typeof(rows) != "string")) { return; } - for (var c=0; c 1) { Init(0); } }, true); +boardShortcut("A3", "load first game", function (t, e) { + if (numberOfGames > 1) { + Init(0); + } +}, true); -boardShortcut("B3", "jump to previous games decile", function(t,e){ if (currentGame > 0) { calculateDeciles(); for (var ii=(deciles.length-2); ii>=0; ii--) { if (currentGame > deciles[ii]) { Init(deciles[ii]); break; } } } }, true); +boardShortcut("B3", "jump to previous games decile", function (t, e) { + if (currentGame > 0) { + calculateDeciles(); + for (var ii = (deciles.length - 2); ii >= 0; ii--) { + if (currentGame > deciles[ii]) { + Init(deciles[ii]); + break; + } + } + } +}, true); -boardShortcut("C3", "load previous game", function(t,e){ Init(currentGame - 1); }, true); +boardShortcut("C3", "load previous game", function (t, e) { + Init(currentGame - 1); +}, true); -boardShortcut("D3", "load random game", function(t,e){ if (numberOfGames > 1) { Init(Math.floor(Math.random()*numberOfGames)); } }, true); +boardShortcut("D3", "load random game", function (t, e) { + if (numberOfGames > 1) { + Init(Math.floor(Math.random() * numberOfGames)); + } +}, true); -boardShortcut("E3", "load random game at random position", function(t,e){ randomGameRandomPly(); }, true); +boardShortcut("E3", "load random game at random position", function (t, e) { + randomGameRandomPly(); +}, true); -boardShortcut("F3", "load next game", function(t,e){ Init(currentGame + 1); }, true); +boardShortcut("F3", "load next game", function (t, e) { + Init(currentGame + 1); +}, true); -boardShortcut("G3", "jump to next games decile", function(t,e){ if (currentGame < numberOfGames - 1) { calculateDeciles(); for (var ii=1; ii 1) { Init(numberOfGames - 1); } }, true); +boardShortcut("H3", "load last game", function (t, e) { + if (numberOfGames > 1) { + Init(numberOfGames - 1); + } +}, true); -boardShortcut("A2", "stop autoplay", function(t,e){ SetAutoPlay(e.shiftKey); }, true); +boardShortcut("A2", "stop autoplay", function (t, e) { + SetAutoPlay(e.shiftKey); +}, true); -boardShortcut("B2", "toggle autoplay", function(t,e){ SwitchAutoPlay(); }, true); +boardShortcut("B2", "toggle autoplay", function (t, e) { + SwitchAutoPlay(); +}, true); -boardShortcut("C2", "autoplay 1 second", function(t,e){ SetAutoplayDelayAndStart((e.shiftKey ? 10 : 1)*1000); }, true); +boardShortcut("C2", "autoplay 1 second", function (t, e) { + SetAutoplayDelayAndStart((e.shiftKey ? 10 : 1) * 1000); +}, true); -boardShortcut("D2", "autoplay 2 seconds", function(t,e){ SetAutoplayDelayAndStart((e.shiftKey ? 20 : 2)*1000); }, true); +boardShortcut("D2", "autoplay 2 seconds", function (t, e) { + SetAutoplayDelayAndStart((e.shiftKey ? 20 : 2) * 1000); +}, true); -boardShortcut("E2", "autoplay 5 seconds", function(t,e){ SetAutoplayDelayAndStart((e.shiftKey ? 50 : 5)*1000); }, true); +boardShortcut("E2", "autoplay 5 seconds", function (t, e) { + SetAutoplayDelayAndStart((e.shiftKey ? 50 : 5) * 1000); +}, true); -boardShortcut("F2", "autoplay custom delay", function(t,e){ setCustomAutoplayDelay(); }, true); +boardShortcut("F2", "autoplay custom delay", function (t, e) { + setCustomAutoplayDelay(); +}, true); -boardShortcut("G2", "replay up to 6 previous half-moves, then autoplay forward", function(t,e){ replayPreviousMoves(e.shiftKey ? 10 : 6); }, true); +boardShortcut("G2", "replay up to 6 previous half-moves, then autoplay forward", function (t, e) { + replayPreviousMoves(e.shiftKey ? 10 : 6); +}, true); -boardShortcut("H2", "replay the previous half-move, then autoplay forward", function(t,e){ replayPreviousMoves(e.shiftKey ? 3 : 1); }, true); +boardShortcut("H2", "replay the previous half-move, then autoplay forward", function (t, e) { + replayPreviousMoves(e.shiftKey ? 3 : 1); +}, true); -boardShortcut("A1", "go to game start", function(t,e){ startButton(e); }, true); +boardShortcut("A1", "go to game start", function (t, e) { + startButton(e); +}, true); -boardShortcut("B1", "", function(t,e){}, true); // see setB1C1F1G1... +boardShortcut("B1", "", function (t, e) { +}, true); // see setB1C1F1G1... -boardShortcut("C1", "", function(t,e){}, true); // see setB1C1F1G1... +boardShortcut("C1", "", function (t, e) { +}, true); // see setB1C1F1G1... -boardShortcut("D1", "move backward", function(t,e){ backButton(e); }, true); +boardShortcut("D1", "move backward", function (t, e) { + backButton(e); +}, true); -boardShortcut("E1", "move forward", function(t,e){ forwardButton(e); }, true); +boardShortcut("E1", "move forward", function (t, e) { + forwardButton(e); +}, true); -boardShortcut("F1", "", function(t,e){}, true); // see setB1C1F1G1... +boardShortcut("F1", "", function (t, e) { +}, true); // see setB1C1F1G1... -boardShortcut("G1", "", function(t,e){}, true); // see setB1C1F1G1... +boardShortcut("G1", "", function (t, e) { +}, true); // see setB1C1F1G1... -boardShortcut("H1", "go to game end", function(t,e){ endButton(e); }, true); +boardShortcut("H1", "go to game end", function (t, e) { + endButton(e); +}, true); setG7A6B6H7boardShortcuts(); function setG7A6B6H7boardShortcuts() { - if (LiveBroadcastDelay > 0) { - if (boardIsDefault("G7")) { boardShortcut("G7", "", function(t,e){}, true); } - if (boardIsDefault("A6")) { boardShortcut("A6", "pause live broadcast automatic games refresh", function(t,e){ pauseLiveBroadcast(); }, true); } - if (boardIsDefault("B6")) { boardShortcut("B6", "restart live broadcast automatic games refresh", function(t,e){ restartLiveBroadcast(); }, true); } - if (boardIsDefault("H6")) { boardShortcut("H6", "force live broadcast games refresh", function(t,e){ refreshPgnSource(); }, true); } - } else { - if (boardIsDefault("G7")) { boardShortcut("G7", "toggle autoplay next game", function(t,e){ SetAutoplayNextGame(!autoplayNextGame); }, true); } - if (boardIsDefault("A6")) { boardShortcut("A6", "", function(t,e){}, true); } - if (boardIsDefault("B6")) { boardShortcut("B6", "", function(t,e){}, true); } - if (boardIsDefault("H6")) { boardShortcut("H6", "", function(t,e){}, true); } - } + if (LiveBroadcastDelay > 0) { + if (boardIsDefault("G7")) { + boardShortcut("G7", "", function (t, e) { + }, true); + } + if (boardIsDefault("A6")) { + boardShortcut("A6", "pause live broadcast automatic games refresh", function (t, e) { + pauseLiveBroadcast(); + }, true); + } + if (boardIsDefault("B6")) { + boardShortcut("B6", "restart live broadcast automatic games refresh", function (t, e) { + restartLiveBroadcast(); + }, true); + } + if (boardIsDefault("H6")) { + boardShortcut("H6", "force live broadcast games refresh", function (t, e) { + refreshPgnSource(); + }, true); + } + } else { + if (boardIsDefault("G7")) { + boardShortcut("G7", "toggle autoplay next game", function (t, e) { + SetAutoplayNextGame(!autoplayNextGame); + }, true); + } + if (boardIsDefault("A6")) { + boardShortcut("A6", "", function (t, e) { + }, true); + } + if (boardIsDefault("B6")) { + boardShortcut("B6", "", function (t, e) { + }, true); + } + if (boardIsDefault("H6")) { + boardShortcut("H6", "", function (t, e) { + }, true); + } + } } setB1C1F1G1boardShortcuts(); function setB1C1F1G1boardShortcuts() { - if (commentsIntoMoveText && GameHasComments) { - if (boardIsDefault("B1")) { boardShortcut("B1", "find previous comment or variation", function(t,e){ if (e.shiftKey) { GoToMove(CurrentPly - 10); } else { MoveToPrevComment(); } }, true); } - if (boardIsDefault("G1")) { boardShortcut("G1", "find next comment or variation", function(t,e){ if (e.shiftKey) { GoToMove(CurrentPly + 10); } else { MoveToNextComment(); } }, true); } - } else { - if (boardIsDefault("B1")) { boardShortcut("B1", "move 10 half-moves backward", function(t,e){ GoToMove(CurrentPly - 10); }, true); } - if (boardIsDefault("G1")) { boardShortcut("G1", "move 10 half-moves forward", function(t,e){ GoToMove(CurrentPly + 10); }, true); } - } - if (commentsIntoMoveText && GameHasVariations) { - if (boardIsDefault("C1")) { boardShortcut("C1", "go to parent variation", function(t,e){ if (e.shiftKey) { GoToMove(CurrentPly - 6); } else { GoToMove(StartPlyVar[CurrentVar]); } }, true); } - if (boardIsDefault("F1")) { boardShortcut("F1", "cycle through alternative variations, if any, otherwise move forward", function(t,e){ if (e.shiftKey) { GoToMove(CurrentPly + 6); } else { if (!goToNextVariationSibling()) { GoToMove(CurrentPly + 1); } } }, true); } - } else { - if (boardIsDefault("C1")) { boardShortcut("C1", "move 6 half-moves backward", function(t,e){ GoToMove(CurrentPly - 6); }, true); } - if (boardIsDefault("F1")) { boardShortcut("F1", "move 6 half-moves forward", function(t,e){ GoToMove(CurrentPly + 6); }, true); } - } + if (commentsIntoMoveText && GameHasComments) { + if (boardIsDefault("B1")) { + boardShortcut("B1", "find previous comment or variation", function (t, e) { + if (e.shiftKey) { + GoToMove(CurrentPly - 10); + } else { + MoveToPrevComment(); + } + }, true); + } + if (boardIsDefault("G1")) { + boardShortcut("G1", "find next comment or variation", function (t, e) { + if (e.shiftKey) { + GoToMove(CurrentPly + 10); + } else { + MoveToNextComment(); + } + }, true); + } + } else { + if (boardIsDefault("B1")) { + boardShortcut("B1", "move 10 half-moves backward", function (t, e) { + GoToMove(CurrentPly - 10); + }, true); + } + if (boardIsDefault("G1")) { + boardShortcut("G1", "move 10 half-moves forward", function (t, e) { + GoToMove(CurrentPly + 10); + }, true); + } + } + if (commentsIntoMoveText && GameHasVariations) { + if (boardIsDefault("C1")) { + boardShortcut("C1", "go to parent variation", function (t, e) { + if (e.shiftKey) { + GoToMove(CurrentPly - 6); + } else { + GoToMove(StartPlyVar[CurrentVar]); + } + }, true); + } + if (boardIsDefault("F1")) { + boardShortcut("F1", "cycle through alternative variations, if any, otherwise move forward", function (t, e) { + if (e.shiftKey) { + GoToMove(CurrentPly + 6); + } else { + if (!goToNextVariationSibling()) { + GoToMove(CurrentPly + 1); + } + } + }, true); + } + } else { + if (boardIsDefault("C1")) { + boardShortcut("C1", "move 6 half-moves backward", function (t, e) { + GoToMove(CurrentPly - 6); + }, true); + } + if (boardIsDefault("F1")) { + boardShortcut("F1", "move 6 half-moves forward", function (t, e) { + GoToMove(CurrentPly + 6); + }, true); + } + } } var deciles = new Array(11); + function calculateDeciles() { - for (var ii=0; ii 1 ? '\nGAME: current=' + (currentGame+1) + ' number=' + numberOfGames : '') + (numberOfVars > 1 ? '\nVARIATION: current=' + CurrentVar + ' number=' + (numberOfVars-1) : '') + (PlyNumber > 0 ? '\nPLY: start=' + StartPly + ' current=' + CurrentPly + ' number=' + PlyNumber : '') + '\nAUTOPLAY: status=' + (isAutoPlayOn ? 'on' : 'off') + ' delay=' + Delay + 'ms' + ' next=' + autoplayNextGame; - if ((typeof(gameVariant[currentGame]) !== "undefined") && (gameVariant[currentGame].match(/^\s*(|chess|normal|standard)\s*$/i) === null)) { - dbg3 += '\nVARIANT: ' + gameVariant[currentGame]; - } - if (LiveBroadcastDelay > 0) { - dbg3 += '\n\nLIVEBROADCAST: status=' + liveStatusDebug() + (LiveBroadcastEndlessMode ? '/endless ' : '') + ' ticker=' + LiveBroadcastTicker + ' delay=' + LiveBroadcastDelay + 'm' + '\n' + 'refreshed: ' + LiveBroadcastLastRefreshedLocal + '\n' + 'received: ' + LiveBroadcastLastReceivedLocal + '\n' + 'modified (server time): ' + LiveBroadcastLastModified_ServerTime(); - } - if (typeof(engineWinCheck) == "function") { - dbg3 += '\n\nANALYSIS: ' + (engineWinCheck() ? 'board=connected ' + engineWin.customDebugInfo() : 'board=disconnected'); - } - var thisInfo = customDebugInfo(); - if (thisInfo) { dbg3 += '\n\nCUSTOM: ' + thisInfo; } - dbg3 += '\n\nALERTLOG: fatalnew=' + fatalErrorNumSinceReset + ' new=' + alertNumSinceReset + ' shown=' + Math.min(alertNum, alertLog.length) + ' total=' + alertNum + '\n--'; - if (alertNum > 0) { - for (var ii = 0; iipgn4web debug info\n
\n" + dbg1 + location.href + " " + dbg3 + "\n
\n"); - debugWin.document.close(); - if (window.focus) { debugWin.focus(); } + dbg3 += '\n' + (numberOfGames > 1 ? '\nGAME: current=' + (currentGame + 1) + ' number=' + numberOfGames : '') + (numberOfVars > 1 ? '\nVARIATION: current=' + CurrentVar + ' number=' + (numberOfVars - 1) : '') + (PlyNumber > 0 ? '\nPLY: start=' + StartPly + ' current=' + CurrentPly + ' number=' + PlyNumber : '') + '\nAUTOPLAY: status=' + (isAutoPlayOn ? 'on' : 'off') + ' delay=' + Delay + 'ms' + ' next=' + autoplayNextGame; + if ((typeof (gameVariant[currentGame]) !== "undefined") && (gameVariant[currentGame].match(/^\s*(|chess|normal|standard)\s*$/i) === null)) { + dbg3 += '\nVARIANT: ' + gameVariant[currentGame]; } - } - alertNumSinceReset = fatalErrorNumSinceReset = 0; + if (LiveBroadcastDelay > 0) { + dbg3 += '\n\nLIVEBROADCAST: status=' + liveStatusDebug() + (LiveBroadcastEndlessMode ? '/endless ' : '') + ' ticker=' + LiveBroadcastTicker + ' delay=' + LiveBroadcastDelay + 'm' + '\n' + 'refreshed: ' + LiveBroadcastLastRefreshedLocal + '\n' + 'received: ' + LiveBroadcastLastReceivedLocal + '\n' + 'modified (server time): ' + LiveBroadcastLastModified_ServerTime(); + } + if (typeof (engineWinCheck) == "function") { + dbg3 += '\n\nANALYSIS: ' + (engineWinCheck() ? 'board=connected ' + engineWin.customDebugInfo() : 'board=disconnected'); + } + var thisInfo = customDebugInfo(); + if (thisInfo) { + dbg3 += '\n\nCUSTOM: ' + thisInfo; + } + dbg3 += '\n\nALERTLOG: fatalnew=' + fatalErrorNumSinceReset + ' new=' + alertNumSinceReset + ' shown=' + Math.min(alertNum, alertLog.length) + ' total=' + alertNum + '\n--'; + if (alertNum > 0) { + for (var ii = 0; ii < alertLog.length; ii++) { + if (alertLog[(alertNum - 1 - ii) % alertLog.length] === undefined) { + break; + } else { + dbg3 += "\n" + alertLog[(alertNum - 1 - ii) % alertLog.length] + "\n--"; + } + } + } + if (confirm(dbg1 + dbg2 + dbg3 + '\n\nclick OK to show this debug info in a browser window for cut and paste')) { + if (debugWin && !debugWin.closed) { + debugWin.close(); + } + debugWin = window.open("", "pgn4web_debug_data", "resizable=yes,scrollbars=yes,toolbar=no,location=no,menubar=no,status=no"); + if (debugWin) { + debugWin.document.open("text/html", "replace"); + debugWin.document.write("pgn4web debug info\n
\n" + dbg1 + location.href + " " + dbg3 + "\n
\n"); + debugWin.document.close(); + if (window.focus) { + debugWin.focus(); + } + } + } + alertNumSinceReset = fatalErrorNumSinceReset = 0; } function liveStatusDebug() { - if (LiveBroadcastEnded) { return "ended"; } - if (LiveBroadcastPaused) { return "paused"; } - if (LiveBroadcastStarted) { return "started"; } - return "waiting"; + if (LiveBroadcastEnded) { + return "ended"; + } + if (LiveBroadcastPaused) { + return "paused"; + } + if (LiveBroadcastStarted) { + return "started"; + } + return "waiting"; } -function customDebugInfo() { return ""; } +function customDebugInfo() { + return ""; +} var pgnWin; + function displayPgnData(oneGameOnly) { - if (pgnWin && !pgnWin.closed) { pgnWin.close(); } - pgnWin = window.open("", "pgn4web_pgn_data", "resizable=yes,scrollbars=yes,toolbar=no,location=no,menubar=no,status=no"); - if (pgnWin) { - var text = "pgn4web PGN source\n
\n";
-    if (oneGameOnly) { text += fullPgnGame(currentGame) + "\n\n"; }
-    else { for (var ii = 0; ii < numberOfGames; ++ii) { text += fullPgnGame(ii) + "\n\n"; } }
-    text += "\n
\n"; - pgnWin.document.open("text/html", "replace"); - pgnWin.document.write(text); - pgnWin.document.close(); - if (window.focus) { pgnWin.focus(); } - } + if (pgnWin && !pgnWin.closed) { + pgnWin.close(); + } + pgnWin = window.open("", "pgn4web_pgn_data", "resizable=yes,scrollbars=yes,toolbar=no,location=no,menubar=no,status=no"); + if (pgnWin) { + var text = "pgn4web PGN source\n
\n";
+        if (oneGameOnly) {
+            text += fullPgnGame(currentGame) + "\n\n";
+        } else {
+            for (var ii = 0; ii < numberOfGames; ++ii) {
+                text += fullPgnGame(ii) + "\n\n";
+            }
+        }
+        text += "\n
\n"; + pgnWin.document.open("text/html", "replace"); + pgnWin.document.write(text); + pgnWin.document.close(); + if (window.focus) { + pgnWin.focus(); + } + } } function savePgnData(oneGameOnly) { - if (pgnUrl && !oneGameOnly) { location.href = pgnUrl; } - else { - displayPgnData(oneGameOnly); // fallback on displayPgnData for now - } + if (pgnUrl && !oneGameOnly) { + location.href = pgnUrl; + } else { + displayPgnData(oneGameOnly); // fallback on displayPgnData for now + } } function CurrentFEN() { - var thisFEN = ""; + var thisFEN = ""; - var emptySquares = 0; - for (var row=7; row>=0; row--) { - for (var col=0; col<=7; col++) { - if (Board[col][row] === 0) { emptySquares++; } - else { - if (emptySquares) { - thisFEN += emptySquares; - emptySquares = 0; + var emptySquares = 0; + for (var row = 7; row >= 0; row--) { + for (var col = 0; col <= 7; col++) { + if (Board[col][row] === 0) { + emptySquares++; + } else { + if (emptySquares) { + thisFEN += emptySquares; + emptySquares = 0; + } + if (Board[col][row] > 0) { + thisFEN += PiecesArr[Board[col][row] - 1].toUpperCase(); + } else if (Board[col][row] < 0) { + thisFEN += PiecesArr[-Board[col][row] - 1].toLowerCase(); + } + } + } + if (emptySquares) { + thisFEN += emptySquares; + emptySquares = 0; + } + if (row > 0) { + thisFEN += "/"; } - if (Board[col][row] > 0) { thisFEN += PiecesArr[Board[col][row]-1].toUpperCase(); } - else if (Board[col][row] < 0) { thisFEN += PiecesArr[-Board[col][row]-1].toLowerCase(); } - } } - if (emptySquares) { - thisFEN += emptySquares; - emptySquares = 0; + + thisFEN += CurrentPly % 2 ? " b" : " w"; + + // castling availability: always in the KQkq form + // knownbug: wrong FEN for Chess960 positions with inner castling rook + var CastlingFEN = ""; + if (RookForOOCastling(0) !== null) { + CastlingFEN += PiecesArr[0].toUpperCase(); } - if (row>0) { thisFEN += "/"; } - } + if (RookForOOOCastling(0) !== null) { + CastlingFEN += PiecesArr[1].toUpperCase(); + } + if (RookForOOCastling(1) !== null) { + CastlingFEN += PiecesArr[0].toLowerCase(); + } + if (RookForOOOCastling(1) !== null) { + CastlingFEN += PiecesArr[1].toLowerCase(); + } + thisFEN += " " + (CastlingFEN || "-"); - thisFEN += CurrentPly%2 ? " b" : " w"; + if (HistEnPassant[CurrentPly]) { + thisFEN += " " + String.fromCharCode(HistEnPassantCol[CurrentPly] + 97); + thisFEN += CurrentPly % 2 ? "3" : "6"; + } else { + thisFEN += " -"; + } - // castling availability: always in the KQkq form - // knownbug: wrong FEN for Chess960 positions with inner castling rook - var CastlingFEN = ""; - if (RookForOOCastling(0) !== null) { CastlingFEN += PiecesArr[0].toUpperCase(); } - if (RookForOOOCastling(0) !== null) { CastlingFEN += PiecesArr[1].toUpperCase(); } - if (RookForOOCastling(1) !== null) { CastlingFEN += PiecesArr[0].toLowerCase(); } - if (RookForOOOCastling(1) !== null) { CastlingFEN += PiecesArr[1].toLowerCase(); } - thisFEN += " " + (CastlingFEN || "-"); + var HalfMoveClock = InitialHalfMoveClock; + for (var thisPly = StartPly; thisPly < CurrentPly; thisPly++) { + if ((HistType[0][thisPly] == 6) || (HistPieceId[1][thisPly] >= 16)) { + HalfMoveClock = 0; + } else { + HalfMoveClock++; + } + } + thisFEN += " " + HalfMoveClock; - if (HistEnPassant[CurrentPly]) { - thisFEN += " " + String.fromCharCode(HistEnPassantCol[CurrentPly] + 97); - thisFEN += CurrentPly%2 ? "3" : "6"; - } else { thisFEN += " -"; } + thisFEN += " " + (Math.floor(CurrentPly / 2) + 1); - var HalfMoveClock = InitialHalfMoveClock; - for (var thisPly = StartPly; thisPly < CurrentPly; thisPly++) { - if ((HistType[0][thisPly] == 6) || (HistPieceId[1][thisPly] >= 16)) { HalfMoveClock = 0; } - else { HalfMoveClock++; } - } - thisFEN += " " + HalfMoveClock; - - thisFEN += " " + (Math.floor(CurrentPly/2)+1); - - return thisFEN; + return thisFEN; } var fenWin; + function displayFenData(addGametext) { - if (fenWin && !fenWin.closed) { fenWin.close(); } - - var thisFEN = CurrentFEN(); - - var movesStr = ""; - var lineStart = 0; - if (addGametext) { - for (var thisPly = CurrentPly; thisPly <= StartPly + PlyNumber; thisPly++) { - var addStr = ""; - if (thisPly == StartPly + PlyNumber) { - addStr = (CurrentVar ? "*" : gameResult[currentGame] || "*"); - } else { - if (thisPly%2 === 0) { addStr = (Math.floor(thisPly/2)+1) + ". "; } - else if (thisPly == CurrentPly) { addStr = (Math.floor(thisPly/2)+1) + "... "; } - addStr += Moves[thisPly]; - } - if (movesStr.length + addStr.length + 1 > lineStart + 80) { - lineStart = movesStr.length; - movesStr += "\n" + addStr; - } else { - if (movesStr.length > 0) { movesStr += " "; } - movesStr += addStr; - } + if (fenWin && !fenWin.closed) { + fenWin.close(); } - } - fenWin = window.open("", "pgn4web_fen_data", "resizable=yes,scrollbars=yes,toolbar=no,location=no,menubar=no,status=no"); - if (fenWin) { - var text = "pgn4web FEN string\n
\n\n" + thisFEN + "\n\n
\n
\n
\n\n";
+    var thisFEN = CurrentFEN();
+
+    var movesStr = "";
+    var lineStart = 0;
     if (addGametext) {
-      text += "[Event \""  + ((CurrentVar ? "" : gameEvent[currentGame])  || "?") + "\"]\n";
-      text += "[Site \""   + ((CurrentVar ? "" : gameSite[currentGame])   || "?") + "\"]\n";
-      text += "[Date \""   + ((CurrentVar ? "" : gameDate[currentGame])   || "????.??.??") + "\"]\n";
-      text += "[Round \""  + ((CurrentVar ? "" : gameRound[currentGame])  || "?") + "\"]\n";
-      text += "[White \""  + ((CurrentVar ? "" : gameWhite[currentGame])  || "?") + "\"]\n";
-      text += "[Black \""  + ((CurrentVar ? "" : gameBlack[currentGame])  || "?") + "\"]\n";
-      text += "[Result \"" + ((CurrentVar ? "" : gameResult[currentGame]) || "*") + "\"]\n";
+        for (var thisPly = CurrentPly; thisPly <= StartPly + PlyNumber; thisPly++) {
+            var addStr = "";
+            if (thisPly == StartPly + PlyNumber) {
+                addStr = (CurrentVar ? "*" : gameResult[currentGame] || "*");
+            } else {
+                if (thisPly % 2 === 0) {
+                    addStr = (Math.floor(thisPly / 2) + 1) + ". ";
+                } else if (thisPly == CurrentPly) {
+                    addStr = (Math.floor(thisPly / 2) + 1) + "... ";
+                }
+                addStr += Moves[thisPly];
+            }
+            if (movesStr.length + addStr.length + 1 > lineStart + 80) {
+                lineStart = movesStr.length;
+                movesStr += "\n" + addStr;
+            } else {
+                if (movesStr.length > 0) {
+                    movesStr += " ";
+                }
+                movesStr += addStr;
+            }
+        }
     }
-    if ((thisFEN != FenStringStart) || (!addGametext)) {
-      text += "[SetUp \"1\"]\n" + "[FEN \"" + thisFEN + "\"]\n";
+
+    fenWin = window.open("", "pgn4web_fen_data", "resizable=yes,scrollbars=yes,toolbar=no,location=no,menubar=no,status=no");
+    if (fenWin) {
+        var text = "pgn4web FEN string\n
\n\n" + thisFEN + "\n\n
\n
\n
\n\n";
+        if (addGametext) {
+            text += "[Event \"" + ((CurrentVar ? "" : gameEvent[currentGame]) || "?") + "\"]\n";
+            text += "[Site \"" + ((CurrentVar ? "" : gameSite[currentGame]) || "?") + "\"]\n";
+            text += "[Date \"" + ((CurrentVar ? "" : gameDate[currentGame]) || "????.??.??") + "\"]\n";
+            text += "[Round \"" + ((CurrentVar ? "" : gameRound[currentGame]) || "?") + "\"]\n";
+            text += "[White \"" + ((CurrentVar ? "" : gameWhite[currentGame]) || "?") + "\"]\n";
+            text += "[Black \"" + ((CurrentVar ? "" : gameBlack[currentGame]) || "?") + "\"]\n";
+            text += "[Result \"" + ((CurrentVar ? "" : gameResult[currentGame]) || "*") + "\"]\n";
+        }
+        if ((thisFEN != FenStringStart) || (!addGametext)) {
+            text += "[SetUp \"1\"]\n" + "[FEN \"" + thisFEN + "\"]\n";
+        }
+        if (gameVariant[currentGame] !== "") {
+            text += "[Variant \"" + gameVariant[currentGame] + "\"]\n";
+        }
+        if (addGametext) {
+            text += "\n" + movesStr + "\n";
+        }
+        text += "
\n"; + fenWin.document.open("text/html", "replace"); + fenWin.document.write(text); + fenWin.document.close(); + if (window.focus) { + fenWin.focus(); + } } - if (gameVariant[currentGame] !== "") { text += "[Variant \"" + gameVariant[currentGame] + "\"]\n"; } - if (addGametext) { text += "\n" + movesStr + "\n"; } - text += "
\n"; - fenWin.document.open("text/html", "replace"); - fenWin.document.write(text); - fenWin.document.close(); - if (window.focus) { fenWin.focus(); } - } } @@ -938,7 +1424,9 @@ var mvCapturedId = -1; var mvIsNull = 0; var Board = new Array(8); -for (var i=0; i<8; ++i) { Board[i] = new Array(8); } +for (var i = 0; i < 8; ++i) { + Board[i] = new Array(8); +} // HistCol, HistRow: move history up to last replayed ply // HistCol[0], HistRow[0]: "square from"; 0..7, 0..7 from A1 @@ -956,18 +1444,18 @@ var PieceRow = new Array(2); var PieceType = new Array(2); var PieceMoveCounter = new Array(2); -for (i=0; i<2; ++i) { - PieceCol[i] = new Array(16); - PieceRow[i] = new Array(16); - PieceType[i] = new Array(16); - PieceMoveCounter[i] = new Array(16); - HistType[i] = new Array(); - HistPieceId[i] = new Array(); +for (i = 0; i < 2; ++i) { + PieceCol[i] = new Array(16); + PieceRow[i] = new Array(16); + PieceType[i] = new Array(16); + PieceMoveCounter[i] = new Array(16); + HistType[i] = new Array(); + HistPieceId[i] = new Array(); } -for (i=0; i<3; ++i) { - HistCol[i] = new Array(); - HistRow[i] = new Array(); +for (i = 0; i < 3; ++i) { + HistCol[i] = new Array(); + HistRow[i] = new Array(); } var HistEnPassant = new Array(); @@ -1011,14 +1499,14 @@ var CurrentPly; var IsRotated = false; -var pgnHeaderTagRegExp = /\[\s*(\w+)\s*"([^"]*)"\s*\]/; +var pgnHeaderTagRegExp = /\[\s*(\w+)\s*"([^"]*)"\s*\]/; var pgnHeaderTagRegExpGlobal = /\[\s*(\w+)\s*"([^"]*)"\s*\]/g; -var pgnHeaderBlockRegExp = /\s*(\[\s*\w+\s*"[^"]*"\s*\]\s*)+/; +var pgnHeaderBlockRegExp = /\s*(\[\s*\w+\s*"[^"]*"\s*\]\s*)+/; var emptyPgnHeader = '[Event ""]\n[Site ""]\n[Date ""]\n[Round ""]\n[White ""]\n[Black ""]\n[Result ""]\n'; var alertPgn = emptyPgnHeader + "\n{error: click on the top left chessboard square for debug info}"; -var pgn4webVariationRegExp = /\[%pgn4web_variation (\d+)\]/; +var pgn4webVariationRegExp = /\[%pgn4web_variation (\d+)\]/; var pgn4webVariationRegExpGlobal = /\[%pgn4web_variation (\d+)\]/g; var gameSelectorHead = ' ···'; @@ -1034,512 +1522,657 @@ var gameSelectorChResult = 0; var gameSelectorChDate = 10; function CheckLegality(what, plyCount) { - var retVal, thisCol; + var retVal, thisCol; - if (what == '--') { - StoreMove(plyCount); - return true; - } - - // castling - if (what == 'O-O') { - if (!CheckLegalityOO()) { return false; } - for (thisCol = PieceCol[MoveColor][0]; thisCol < 7; thisCol++) { - if (IsCheck(thisCol, MoveColor*7, MoveColor)) { return false; } - } - StoreMove(plyCount); - return true; - } else if (what == 'O-O-O') { - if (!CheckLegalityOOO()) { return false; } - for (thisCol = PieceCol[MoveColor][0]; thisCol > 1; thisCol--) { - if (IsCheck(thisCol, MoveColor*7, MoveColor)) { return false; } - } - StoreMove(plyCount); - return true; - } - - // capture: "square to" occupied by opposite color piece (except en-passant) - if (!mvCapture) { - if (Board[mvToCol][mvToRow] !== 0) { return false; } - } - if ((mvCapture) && (Color(Board[mvToCol][mvToRow]) != 1-MoveColor)) { - if ((mvPiece != 6) || (!HistEnPassant[plyCount]) || (HistEnPassantCol[plyCount] != mvToCol) || (mvToRow != 5-3*MoveColor)) { return false; } - } - - // promotion: "square to" moved piece different from piece - if (mvIsPromotion) { - if (mvPiece != 6) { return false; } - if (mvPieceOnTo >= 6) { return false; } - if (mvToRow != 7*(1-MoveColor)) { return false; } - } - - // piece move: which same type piece could move there? - var howManyCandidates = 0; - var candidatePieceId = -1; - for (var pieceId = 15; pieceId >= 0; --pieceId) { - if (PieceType[MoveColor][pieceId] == mvPiece) { - if (mvPiece == 1) { retVal = CheckLegalityKing(pieceId); } - else if (mvPiece == 2) { retVal = CheckLegalityQueen(pieceId); } - else if (mvPiece == 3) { retVal = CheckLegalityRook(pieceId); } - else if (mvPiece == 4) { retVal = CheckLegalityBishop(pieceId); } - else if (mvPiece == 5) { retVal = CheckLegalityKnight(pieceId); } - else if (mvPiece == 6) { retVal = CheckLegalityPawn(pieceId); } - if (retVal) { - // board updated: king in check? - mvPieceId = pieceId; + if (what == '--') { StoreMove(plyCount); - if (!IsCheck(PieceCol[MoveColor][0], PieceRow[MoveColor][0], MoveColor)) { - howManyCandidates++; - candidatePieceId = pieceId; - } - UndoMove(plyCount); - } + return true; + } + + // castling + if (what == 'O-O') { + if (!CheckLegalityOO()) { + return false; + } + for (thisCol = PieceCol[MoveColor][0]; thisCol < 7; thisCol++) { + if (IsCheck(thisCol, MoveColor * 7, MoveColor)) { + return false; + } + } + StoreMove(plyCount); + return true; + } else if (what == 'O-O-O') { + if (!CheckLegalityOOO()) { + return false; + } + for (thisCol = PieceCol[MoveColor][0]; thisCol > 1; thisCol--) { + if (IsCheck(thisCol, MoveColor * 7, MoveColor)) { + return false; + } + } + StoreMove(plyCount); + return true; + } + + // capture: "square to" occupied by opposite color piece (except en-passant) + if (!mvCapture) { + if (Board[mvToCol][mvToRow] !== 0) { + return false; + } + } + if ((mvCapture) && (Color(Board[mvToCol][mvToRow]) != 1 - MoveColor)) { + if ((mvPiece != 6) || (!HistEnPassant[plyCount]) || (HistEnPassantCol[plyCount] != mvToCol) || (mvToRow != 5 - 3 * MoveColor)) { + return false; + } + } + + // promotion: "square to" moved piece different from piece + if (mvIsPromotion) { + if (mvPiece != 6) { + return false; + } + if (mvPieceOnTo >= 6) { + return false; + } + if (mvToRow != 7 * (1 - MoveColor)) { + return false; + } + } + + // piece move: which same type piece could move there? + var howManyCandidates = 0; + var candidatePieceId = -1; + for (var pieceId = 15; pieceId >= 0; --pieceId) { + if (PieceType[MoveColor][pieceId] == mvPiece) { + if (mvPiece == 1) { + retVal = CheckLegalityKing(pieceId); + } else if (mvPiece == 2) { + retVal = CheckLegalityQueen(pieceId); + } else if (mvPiece == 3) { + retVal = CheckLegalityRook(pieceId); + } else if (mvPiece == 4) { + retVal = CheckLegalityBishop(pieceId); + } else if (mvPiece == 5) { + retVal = CheckLegalityKnight(pieceId); + } else if (mvPiece == 6) { + retVal = CheckLegalityPawn(pieceId); + } + if (retVal) { + // board updated: king in check? + mvPieceId = pieceId; + StoreMove(plyCount); + if (!IsCheck(PieceCol[MoveColor][0], PieceRow[MoveColor][0], MoveColor)) { + howManyCandidates++; + candidatePieceId = pieceId; + } + UndoMove(plyCount); + } + } } - } // patch: for rejecting rather than guessing ambiguous move replace the code till the end of this function with the following line // if (howManyCandidates == 1) { mvPieceId = candidatePieceId; StoreMove(plyCount); return true; } else { return false; } - if (howManyCandidates > 0) { - mvPieceId = candidatePieceId; - StoreMove(plyCount); - if (howManyCandidates > 1) { - var text = (Math.floor(plyCount / 2) + 1) + ((plyCount % 2) === 0 ? '. ' : '... '); - myAlert('error: guessed ambiguous ply ' + text + MovesVar[CurrentVar][plyCount] + ' in game ' + (currentGame+1) + ' variation ' + CurrentVar); + if (howManyCandidates > 0) { + mvPieceId = candidatePieceId; + StoreMove(plyCount); + if (howManyCandidates > 1) { + var text = (Math.floor(plyCount / 2) + 1) + ((plyCount % 2) === 0 ? '. ' : '... '); + myAlert('error: guessed ambiguous ply ' + text + MovesVar[CurrentVar][plyCount] + ' in game ' + (currentGame + 1) + ' variation ' + CurrentVar); + } + return true; } - return true; - } - return false; + return false; } function CheckLegalityKing(thisKing) { - if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisKing])) { return false; } - if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisKing])) { return false; } - if (Math.abs(PieceCol[MoveColor][thisKing]-mvToCol) > 1) { return false; } - if (Math.abs(PieceRow[MoveColor][thisKing]-mvToRow) > 1) { return false; } - return true; + if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisKing])) { + return false; + } + if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisKing])) { + return false; + } + if (Math.abs(PieceCol[MoveColor][thisKing] - mvToCol) > 1) { + return false; + } + if (Math.abs(PieceRow[MoveColor][thisKing] - mvToRow) > 1) { + return false; + } + return true; } function CheckLegalityQueen(thisQueen) { - if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisQueen])) { return false; } - if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisQueen])) { return false; } - if (((PieceCol[MoveColor][thisQueen]-mvToCol) * (PieceRow[MoveColor][thisQueen]-mvToRow) !== 0) && (Math.abs(PieceCol[MoveColor][thisQueen]-mvToCol) != Math.abs(PieceRow[MoveColor][thisQueen]-mvToRow))) { return false; } - if (!CheckClearWay(thisQueen)) { return false; } - return true; + if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisQueen])) { + return false; + } + if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisQueen])) { + return false; + } + if (((PieceCol[MoveColor][thisQueen] - mvToCol) * (PieceRow[MoveColor][thisQueen] - mvToRow) !== 0) && (Math.abs(PieceCol[MoveColor][thisQueen] - mvToCol) != Math.abs(PieceRow[MoveColor][thisQueen] - mvToRow))) { + return false; + } + if (!CheckClearWay(thisQueen)) { + return false; + } + return true; } function CheckLegalityRook(thisRook) { - if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisRook])) { return false; } - if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisRook])) { return false; } - if ((PieceCol[MoveColor][thisRook]-mvToCol) * (PieceRow[MoveColor][thisRook]-mvToRow) !== 0) { return false; } - if (!CheckClearWay(thisRook)) { return false; } - return true; + if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisRook])) { + return false; + } + if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisRook])) { + return false; + } + if ((PieceCol[MoveColor][thisRook] - mvToCol) * (PieceRow[MoveColor][thisRook] - mvToRow) !== 0) { + return false; + } + if (!CheckClearWay(thisRook)) { + return false; + } + return true; } function CheckLegalityBishop(thisBishop) { - if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisBishop])) { return false; } - if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisBishop])) { return false; } - if (Math.abs(PieceCol[MoveColor][thisBishop]-mvToCol) != Math.abs(PieceRow[MoveColor][thisBishop]-mvToRow)) { return false; } - if (!CheckClearWay(thisBishop)) { return false; } - return true; + if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisBishop])) { + return false; + } + if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisBishop])) { + return false; + } + if (Math.abs(PieceCol[MoveColor][thisBishop] - mvToCol) != Math.abs(PieceRow[MoveColor][thisBishop] - mvToRow)) { + return false; + } + if (!CheckClearWay(thisBishop)) { + return false; + } + return true; } function CheckLegalityKnight(thisKnight) { - if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisKnight])) { return false; } - if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisKnight])) { return false; } - if (Math.abs(PieceCol[MoveColor][thisKnight]-mvToCol) * Math.abs(PieceRow[MoveColor][thisKnight]-mvToRow) != 2) { return false; } - return true; + if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisKnight])) { + return false; + } + if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisKnight])) { + return false; + } + if (Math.abs(PieceCol[MoveColor][thisKnight] - mvToCol) * Math.abs(PieceRow[MoveColor][thisKnight] - mvToRow) != 2) { + return false; + } + return true; } function CheckLegalityPawn(thisPawn) { - if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisPawn])) { return false; } - if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisPawn])) { return false; } - if (Math.abs(PieceCol[MoveColor][thisPawn]-mvToCol) != mvCapture) { return false; } - if (mvCapture) { - if (PieceRow[MoveColor][thisPawn]-mvToRow != 2*MoveColor-1) { return false; } - } else { - if (PieceRow[MoveColor][thisPawn]-mvToRow == 4*MoveColor-2) { - if (PieceRow[MoveColor][thisPawn] != 1+5*MoveColor) { return false; } - if (Board[mvToCol][mvToRow+2*MoveColor-1] !== 0) { return false; } - } else { - if (PieceRow[MoveColor][thisPawn]-mvToRow != 2*MoveColor-1) { return false; } + if ((mvFromCol >= 0) && (mvFromCol != PieceCol[MoveColor][thisPawn])) { + return false; } - } - return true; + if ((mvFromRow >= 0) && (mvFromRow != PieceRow[MoveColor][thisPawn])) { + return false; + } + if (Math.abs(PieceCol[MoveColor][thisPawn] - mvToCol) != mvCapture) { + return false; + } + if (mvCapture) { + if (PieceRow[MoveColor][thisPawn] - mvToRow != 2 * MoveColor - 1) { + return false; + } + } else { + if (PieceRow[MoveColor][thisPawn] - mvToRow == 4 * MoveColor - 2) { + if (PieceRow[MoveColor][thisPawn] != 1 + 5 * MoveColor) { + return false; + } + if (Board[mvToCol][mvToRow + 2 * MoveColor - 1] !== 0) { + return false; + } + } else { + if (PieceRow[MoveColor][thisPawn] - mvToRow != 2 * MoveColor - 1) { + return false; + } + } + } + return true; } function RookForOOCastling(color) { - if (CastlingShort[color] < 0) { return null; } - if (PieceMoveCounter[color][0] > 0) { return null; } - - var legal = false; - for (var thisRook = 0; thisRook < 16; thisRook++) { - if ((PieceCol[color][thisRook] == CastlingShort[color]) && (PieceCol[color][thisRook] > PieceCol[color][0]) && (PieceRow[color][thisRook] == color*7) && (PieceType[color][thisRook] == 3)) { - legal = true; - break; + if (CastlingShort[color] < 0) { + return null; + } + if (PieceMoveCounter[color][0] > 0) { + return null; } - } - if (!legal) { return null; } - if (PieceMoveCounter[color][thisRook] > 0) { return null; } - return thisRook; + var legal = false; + for (var thisRook = 0; thisRook < 16; thisRook++) { + if ((PieceCol[color][thisRook] == CastlingShort[color]) && (PieceCol[color][thisRook] > PieceCol[color][0]) && (PieceRow[color][thisRook] == color * 7) && (PieceType[color][thisRook] == 3)) { + legal = true; + break; + } + } + if (!legal) { + return null; + } + if (PieceMoveCounter[color][thisRook] > 0) { + return null; + } + + return thisRook; } function CheckLegalityOO() { - var thisRook = RookForOOCastling(MoveColor); - if (thisRook === null) { return false; } + var thisRook = RookForOOCastling(MoveColor); + if (thisRook === null) { + return false; + } - // check no piece between king and rook - // clear king/rook squares for Chess960 - Board[PieceCol[MoveColor][0]][MoveColor*7] = 0; - Board[PieceCol[MoveColor][thisRook]][MoveColor*7] = 0; - var col = PieceCol[MoveColor][thisRook]; - if (col < 6) { col = 6; } - while ((col > PieceCol[MoveColor][0]) || (col >= 5)) { - if (Board[col][MoveColor*7] !== 0) { return false; } - --col; - } - castleRook = thisRook; - return true; + // check no piece between king and rook + // clear king/rook squares for Chess960 + Board[PieceCol[MoveColor][0]][MoveColor * 7] = 0; + Board[PieceCol[MoveColor][thisRook]][MoveColor * 7] = 0; + var col = PieceCol[MoveColor][thisRook]; + if (col < 6) { + col = 6; + } + while ((col > PieceCol[MoveColor][0]) || (col >= 5)) { + if (Board[col][MoveColor * 7] !== 0) { + return false; + } + --col; + } + castleRook = thisRook; + return true; } function RookForOOOCastling(color) { - if (CastlingLong[color] < 0) { return null; } - if (PieceMoveCounter[color][0] > 0) { return null; } - - var legal = false; - for (var thisRook = 0; thisRook < 16; thisRook++) { - if ((PieceCol[color][thisRook] == CastlingLong[color]) && (PieceCol[color][thisRook] < PieceCol[color][0]) && (PieceRow[color][thisRook] == color*7) && (PieceType[color][thisRook] == 3)) { - legal = true; - break; + if (CastlingLong[color] < 0) { + return null; + } + if (PieceMoveCounter[color][0] > 0) { + return null; } - } - if (!legal) { return null; } - if (PieceMoveCounter[color][thisRook] > 0) { return null; } - return thisRook; + var legal = false; + for (var thisRook = 0; thisRook < 16; thisRook++) { + if ((PieceCol[color][thisRook] == CastlingLong[color]) && (PieceCol[color][thisRook] < PieceCol[color][0]) && (PieceRow[color][thisRook] == color * 7) && (PieceType[color][thisRook] == 3)) { + legal = true; + break; + } + } + if (!legal) { + return null; + } + if (PieceMoveCounter[color][thisRook] > 0) { + return null; + } + + return thisRook; } function CheckLegalityOOO() { - var thisRook = RookForOOOCastling(MoveColor); - if (thisRook === null) { return false; } + var thisRook = RookForOOOCastling(MoveColor); + if (thisRook === null) { + return false; + } - // check no piece between king and rook - // clear king/rook squares for Chess960 - Board[PieceCol[MoveColor][0]][MoveColor*7] = 0; - Board[PieceCol[MoveColor][thisRook]][MoveColor*7] = 0; - var col = PieceCol[MoveColor][thisRook]; - if (col > 2) { col = 2; } - while ((col < PieceCol[MoveColor][0]) || (col <= 3)) { - if (Board[col][MoveColor*7] !== 0) { return false; } - ++col; - } - castleRook = thisRook; - return true; + // check no piece between king and rook + // clear king/rook squares for Chess960 + Board[PieceCol[MoveColor][0]][MoveColor * 7] = 0; + Board[PieceCol[MoveColor][thisRook]][MoveColor * 7] = 0; + var col = PieceCol[MoveColor][thisRook]; + if (col > 2) { + col = 2; + } + while ((col < PieceCol[MoveColor][0]) || (col <= 3)) { + if (Board[col][MoveColor * 7] !== 0) { + return false; + } + ++col; + } + castleRook = thisRook; + return true; } function CheckClearWay(thisPiece) { - var stepCol = sign(mvToCol-PieceCol[MoveColor][thisPiece]); - var stepRow = sign(mvToRow-PieceRow[MoveColor][thisPiece]); - var startCol = PieceCol[MoveColor][thisPiece]+stepCol; - var startRow = PieceRow[MoveColor][thisPiece]+stepRow; - while ((startCol != mvToCol) || (startRow != mvToRow)) { - if (Board[startCol][startRow] !== 0) { return false; } - startCol += stepCol; - startRow += stepRow; - } - return true; + var stepCol = sign(mvToCol - PieceCol[MoveColor][thisPiece]); + var stepRow = sign(mvToRow - PieceRow[MoveColor][thisPiece]); + var startCol = PieceCol[MoveColor][thisPiece] + stepCol; + var startRow = PieceRow[MoveColor][thisPiece] + stepRow; + while ((startCol != mvToCol) || (startRow != mvToRow)) { + if (Board[startCol][startRow] !== 0) { + return false; + } + startCol += stepCol; + startRow += stepRow; + } + return true; } function CleanMove(move) { - move = move.replace(/[^a-wyzA-WYZ0-9#-]*/g, ''); // patch: pgn notation: remove/add '+' 'x' '=' chars for full chess informant style or pgn style for the game text - if (move.match(/^[Oo0]/)) { move = move.replace(/[o0]/g, 'O').replace(/O(?=O)/g, 'O-'); } - move = move.replace(/ep/i, ''); - return move; + move = move.replace(/[^a-wyzA-WYZ0-9#-]*/g, ''); // patch: pgn notation: remove/add '+' 'x' '=' chars for full chess informant style or pgn style for the game text + if (move.match(/^[Oo0]/)) { + move = move.replace(/[o0]/g, 'O').replace(/O(?=O)/g, 'O-'); + } + move = move.replace(/ep/i, ''); + return move; } function GoToMove(thisPly, thisVar) { - SetAutoPlay(false); - if (typeof(thisVar) == "undefined") { thisVar = CurrentVar; } - else { - if (thisVar < 0) { thisVar = 0; } - else if (thisVar >= numberOfVars) { thisVar = numberOfVars - 1; } - } - if (thisPly < 0) { thisPly = 0; } - else if (thisPly >= StartPlyVar[thisVar] + PlyNumberVar[thisVar]) { - thisPly = StartPlyVar[thisVar] + PlyNumberVar[thisVar]; - } - - if (thisVar === CurrentVar) { - var diff = thisPly - CurrentPly; - if (diff > 0) { MoveForward(diff); } - else { MoveBackward(-diff); } - } else { - var backStart = StartPly; -loopCommonPredecessor: - for (var ii = PredecessorsVars[CurrentVar].length - 1; ii >= 0; ii--) { - for (var jj = PredecessorsVars[thisVar].length - 1; jj >= 0; jj--) { - if (PredecessorsVars[CurrentVar][ii] === PredecessorsVars[thisVar][jj]) { - backStart = Math.min(PredecessorsVars[CurrentVar][ii+1] ? StartPlyVar[PredecessorsVars[CurrentVar][ii+1]] : CurrentPly, PredecessorsVars[thisVar][jj+1] ? StartPlyVar[PredecessorsVars[thisVar][jj+1]] : thisPly); - break loopCommonPredecessor; + SetAutoPlay(false); + if (typeof (thisVar) == "undefined") { + thisVar = CurrentVar; + } else { + if (thisVar < 0) { + thisVar = 0; + } else if (thisVar >= numberOfVars) { + thisVar = numberOfVars - 1; } - } } - MoveBackward(CurrentPly - backStart, true); - MoveForward(thisPly - backStart, thisVar); - } + if (thisPly < 0) { + thisPly = 0; + } else if (thisPly >= StartPlyVar[thisVar] + PlyNumberVar[thisVar]) { + thisPly = StartPlyVar[thisVar] + PlyNumberVar[thisVar]; + } + + if (thisVar === CurrentVar) { + var diff = thisPly - CurrentPly; + if (diff > 0) { + MoveForward(diff); + } else { + MoveBackward(-diff); + } + } else { + var backStart = StartPly; + loopCommonPredecessor: + for (var ii = PredecessorsVars[CurrentVar].length - 1; ii >= 0; ii--) { + for (var jj = PredecessorsVars[thisVar].length - 1; jj >= 0; jj--) { + if (PredecessorsVars[CurrentVar][ii] === PredecessorsVars[thisVar][jj]) { + backStart = Math.min(PredecessorsVars[CurrentVar][ii + 1] ? StartPlyVar[PredecessorsVars[CurrentVar][ii + 1]] : CurrentPly, PredecessorsVars[thisVar][jj + 1] ? StartPlyVar[PredecessorsVars[thisVar][jj + 1]] : thisPly); + break loopCommonPredecessor; + } + } + } + MoveBackward(CurrentPly - backStart, true); + MoveForward(thisPly - backStart, thisVar); + } } function SetShortcutKeysEnabled(onOff) { - shortcutKeysEnabled = onOff; + shortcutKeysEnabled = onOff; } function interactivelyToggleShortcutKeys() { - if (confirm("Shortcut keys currently " + (shortcutKeysEnabled ? "enabled" : "disabled") + ".\nToggle shortcut keys to " + (shortcutKeysEnabled ? "DISABLED" : "ENABLED") + "?")) { - SetShortcutKeysEnabled(!shortcutKeysEnabled); - } + if (confirm("Shortcut keys currently " + (shortcutKeysEnabled ? "enabled" : "disabled") + ".\nToggle shortcut keys to " + (shortcutKeysEnabled ? "DISABLED" : "ENABLED") + "?")) { + SetShortcutKeysEnabled(!shortcutKeysEnabled); + } } function SetCommentsIntoMoveText(onOff) { - commentsIntoMoveText = onOff; + commentsIntoMoveText = onOff; } function SetCommentsOnSeparateLines(onOff) { - commentsOnSeparateLines = onOff; + commentsOnSeparateLines = onOff; } function SetAutostartAutoplay(onOff) { - autostartAutoplay = onOff; + autostartAutoplay = onOff; } function SetAutoplayNextGame(onOff) { - autoplayNextGame = onOff; + autoplayNextGame = onOff; } function SetInitialHalfmove(number_or_string, always) { - alwaysInitialHalfmove = (always === true); - initialHalfmove = typeof(number_or_string) == "undefined" ? 0 : number_or_string; + alwaysInitialHalfmove = (always === true); + initialHalfmove = typeof (number_or_string) == "undefined" ? 0 : number_or_string; } function SetInitialVariation(number) { - initialVariation = isNaN(number = parseInt(number, 10)) ? 0 : number; + initialVariation = isNaN(number = parseInt(number, 10)) ? 0 : number; } function SetInitialGame(number_or_string) { - initialGame = typeof(number_or_string) == "undefined" ? 1 : number_or_string; + initialGame = typeof (number_or_string) == "undefined" ? 1 : number_or_string; } function randomGameRandomPly() { - if (numberOfGames > 1) { - var oldInitialHalfmove = initialHalfmove; - var oldAlwaysInitialHalfmove = alwaysInitialHalfmove; - SetInitialHalfmove("random", true); - Init(Math.floor(Math.random()*numberOfGames)); - SetInitialHalfmove(oldInitialHalfmove, oldAlwaysInitialHalfmove); - } + if (numberOfGames > 1) { + var oldInitialHalfmove = initialHalfmove; + var oldAlwaysInitialHalfmove = alwaysInitialHalfmove; + SetInitialHalfmove("random", true); + Init(Math.floor(Math.random() * numberOfGames)); + SetInitialHalfmove(oldInitialHalfmove, oldAlwaysInitialHalfmove); + } } // clock detection as [%clk 01:02] function clockFromComment(plyNum) { - return customPgnCommentTag("clk", null, plyNum); + return customPgnCommentTag("clk", null, plyNum); } function clockFromHeader(whiteToMove) { - var clockString = customPgnHeaderTag("Clock") + ""; - var matches = clockString.match("^" + (whiteToMove ? "W" : "B") + "/(.*)$"); - if (matches) { return matches[1]; } - else { return null; } + var clockString = customPgnHeaderTag("Clock") + ""; + var matches = clockString.match("^" + (whiteToMove ? "W" : "B") + "/(.*)$"); + if (matches) { + return matches[1]; + } else { + return null; + } } function HighlightLastMove() { - var theObj, moveId, text, ii, clockString, clockRegExp, clockMatch; + var theObj, moveId, text, ii, clockString, clockRegExp, clockMatch; - undoStackStore(); + undoStackStore(); - // remove old move highlighting - if (highlightedMoveId) { - if (theObj = document.getElementById(highlightedMoveId)) { - theObj.className = (highlightedMoveId.match(/Var0Mv/) ? 'move' : 'variation') + ' notranslate'; - } - } - - // halfmove to be highlighted, negative for starting position - var showThisMove = CurrentPly - 1; - if (showThisMove > StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]) { showThisMove = StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]; } - - if (theObj = document.getElementById("GameLastComment")) { - if (commentsIntoMoveText) { - variationTextDepth = CurrentVar === 0 ? 0 : 1; - text = '' + strippedMoveComment(showThisMove+1, CurrentVar, true).replace(/\sID="[^"]*"/g, '') + ''; - } else { text = ''; } - theObj.innerHTML = text; - } - - // side to move - var whiteToMove = ((showThisMove+1)%2 === 0); - text = whiteToMove ? 'white' : 'black'; - - if (theObj = document.getElementById("GameSideToMove")) { theObj.innerHTML = text; } - - // clock - var lastMoverClockObj = document.getElementById(whiteToMove ? "GameBlackClock" : "GameWhiteClock"); - var initialLastMoverClock = whiteToMove ? gameInitialBlackClock[currentGame] : gameInitialWhiteClock[currentGame]; - var beforeLastMoverClockObj = document.getElementById(whiteToMove ? "GameWhiteClock" : "GameBlackClock"); - var initialBeforeLastMoverClock = whiteToMove ? gameInitialWhiteClock[currentGame] : gameInitialBlackClock[currentGame]; - - if (lastMoverClockObj) { - clockString = ((showThisMove+1 === StartPly+PlyNumber) && ((!LiveBroadcastDemo) || (gameResult[currentGame] !== "*"))) ? clockFromHeader(!whiteToMove) : null; - if (clockString === null) { - clockString = showThisMove+1 > StartPly ? clockFromComment(showThisMove+1) : initialLastMoverClock; - if (!clockString && (CurrentPly === StartPly+PlyNumber)) { - // support for time info in the last comment as { White Time: 0h:12min Black Time: 1h:23min } - clockRegExp = new RegExp((whiteToMove ? "Black" : "White") + "\\s+Time:\\s*(\\S+)", "i"); - if (clockMatch = strippedMoveComment(StartPly+PlyNumber).match(clockRegExp)) { - clockString = clockMatch[1]; + // remove old move highlighting + if (highlightedMoveId) { + if (theObj = document.getElementById(highlightedMoveId)) { + theObj.className = (highlightedMoveId.match(/Var0Mv/) ? 'move' : 'variation') + ' notranslate'; } - } } - lastMoverClockObj.innerHTML = clockString; - } - if (beforeLastMoverClockObj) { - clockString = ((showThisMove+1 === StartPly+PlyNumber) && ((!LiveBroadcastDemo) || (gameResult[currentGame] !== "*"))) ? clockFromHeader(whiteToMove) : null; - if (clockString === null) { - clockString = showThisMove > StartPly ? clockFromComment(showThisMove) : initialBeforeLastMoverClock; - if (!clockString && (CurrentPly === StartPly+PlyNumber)) { - // see comment above - clockRegExp = new RegExp((whiteToMove ? "White" : "Black") + "\\s+Time:\\s*(\\S+)", "i"); - if (clockMatch = strippedMoveComment(StartPly+PlyNumber).match(clockRegExp)) { - clockString = clockMatch[1]; + + // halfmove to be highlighted, negative for starting position + var showThisMove = CurrentPly - 1; + if (showThisMove > StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]) { + showThisMove = StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]; + } + + if (theObj = document.getElementById("GameLastComment")) { + if (commentsIntoMoveText) { + variationTextDepth = CurrentVar === 0 ? 0 : 1; + text = '' + strippedMoveComment(showThisMove + 1, CurrentVar, true).replace(/\sID="[^"]*"/g, '') + ''; + } else { + text = ''; } - } + theObj.innerHTML = text; } - beforeLastMoverClockObj.innerHTML = clockString; - } - if (lastMoverClockObj && beforeLastMoverClockObj) { - if (lastMoverClockObj.innerHTML && !beforeLastMoverClockObj.innerHTML) { - beforeLastMoverClockObj.innerHTML = "-"; - } else if (!lastMoverClockObj.innerHTML && beforeLastMoverClockObj.innerHTML) { - lastMoverClockObj.innerHTML = "-"; + // side to move + var whiteToMove = ((showThisMove + 1) % 2 === 0); + text = whiteToMove ? 'white' : 'black'; + + if (theObj = document.getElementById("GameSideToMove")) { + theObj.innerHTML = text; } - } - // next move - if (theObj = document.getElementById("GameNextMove")) { - if (CurrentVar === 0 && showThisMove + 1 >= StartPly + PlyNumber) { - text = '' + gameResult[currentGame] + ''; - } else if (typeof(Moves[showThisMove+1]) == "undefined") { - text = ""; - } else { - text = printMoveText(showThisMove+1, CurrentVar, (CurrentVar !== 0), true, false); - } - theObj.innerHTML = text; - } + // clock + var lastMoverClockObj = document.getElementById(whiteToMove ? "GameBlackClock" : "GameWhiteClock"); + var initialLastMoverClock = whiteToMove ? gameInitialBlackClock[currentGame] : gameInitialWhiteClock[currentGame]; + var beforeLastMoverClockObj = document.getElementById(whiteToMove ? "GameWhiteClock" : "GameBlackClock"); + var initialBeforeLastMoverClock = whiteToMove ? gameInitialWhiteClock[currentGame] : gameInitialBlackClock[currentGame]; - // next variations - if (theObj = document.getElementById("GameNextVariations")) { - text = ''; - if (commentsIntoMoveText) { - var children = childrenVars(showThisMove+1, CurrentVar); - for (ii = 0; ii < children.length; ii++) { - if (children[ii] !== CurrentVar) { - text += ' ' + printMoveText(showThisMove+1, children[ii], (children[ii] !== 0), true, false); + if (lastMoverClockObj) { + clockString = ((showThisMove + 1 === StartPly + PlyNumber) && ((!LiveBroadcastDemo) || (gameResult[currentGame] !== "*"))) ? clockFromHeader(!whiteToMove) : null; + if (clockString === null) { + clockString = showThisMove + 1 > StartPly ? clockFromComment(showThisMove + 1) : initialLastMoverClock; + if (!clockString && (CurrentPly === StartPly + PlyNumber)) { + // support for time info in the last comment as { White Time: 0h:12min Black Time: 1h:23min } + clockRegExp = new RegExp((whiteToMove ? "Black" : "White") + "\\s+Time:\\s*(\\S+)", "i"); + if (clockMatch = strippedMoveComment(StartPly + PlyNumber).match(clockRegExp)) { + clockString = clockMatch[1]; + } + } } - } + lastMoverClockObj.innerHTML = clockString; } - theObj.innerHTML = text; - } - - // last move - if (theObj = document.getElementById("GameLastMove")) { - if ((showThisMove >= StartPly) && Moves[showThisMove]) { - text = printMoveText(showThisMove, CurrentVar, (CurrentVar !== 0), true, false); - } else if (showThisMove === StartPly - 1) { - text = '' + (Math.floor((showThisMove+1)/2) + 1) + (((showThisMove+1) % 2) ? "..." : ".") + ''; - } else { text = ''; } - theObj.innerHTML = text; - } - - // last variations - if (theObj = document.getElementById("GameLastVariations")) { - text = ''; - if (commentsIntoMoveText) { - var siblings = childrenVars(showThisMove, HistVar[showThisMove]); - for (ii = 0; ii < siblings.length; ii++) { - if (siblings[ii] !== CurrentVar) { - text += ' ' + printMoveText(showThisMove, siblings[ii], (siblings[ii] !== 0), true, false); + if (beforeLastMoverClockObj) { + clockString = ((showThisMove + 1 === StartPly + PlyNumber) && ((!LiveBroadcastDemo) || (gameResult[currentGame] !== "*"))) ? clockFromHeader(whiteToMove) : null; + if (clockString === null) { + clockString = showThisMove > StartPly ? clockFromComment(showThisMove) : initialBeforeLastMoverClock; + if (!clockString && (CurrentPly === StartPly + PlyNumber)) { + // see comment above + clockRegExp = new RegExp((whiteToMove ? "White" : "Black") + "\\s+Time:\\s*(\\S+)", "i"); + if (clockMatch = strippedMoveComment(StartPly + PlyNumber).match(clockRegExp)) { + clockString = clockMatch[1]; + } + } } - } + beforeLastMoverClockObj.innerHTML = clockString; } - theObj.innerHTML = text; - } - if (showThisMove >= (StartPlyVar[CurrentVar]-1)) { - moveId = 'Var' + CurrentVar + 'Mv' + (showThisMove + 1); - if (theObj = document.getElementById(moveId)) { - theObj.className = (CurrentVar ? 'variation variationOn' : 'move moveOn') + ' notranslate'; + if (lastMoverClockObj && beforeLastMoverClockObj) { + if (lastMoverClockObj.innerHTML && !beforeLastMoverClockObj.innerHTML) { + beforeLastMoverClockObj.innerHTML = "-"; + } else if (!lastMoverClockObj.innerHTML && beforeLastMoverClockObj.innerHTML) { + lastMoverClockObj.innerHTML = "-"; + } } - highlightedMoveId = moveId; - if (highlightOption) { - var colFrom, rowFrom, colTo, rowTo; - if ((showThisMove < StartPly) || HistNull[showThisMove]) { - colFrom = rowFrom = -1; - colTo = rowTo = -1; - } else { - colFrom = HistCol[0][showThisMove] === undefined ? -1 : HistCol[0][showThisMove]; - rowFrom = HistRow[0][showThisMove] === undefined ? -1 : HistRow[0][showThisMove]; - colTo = HistCol[2][showThisMove] === undefined ? -1 : HistCol[2][showThisMove]; - rowTo = HistRow[2][showThisMove] === undefined ? -1 : HistRow[2][showThisMove]; - } - highlightMove(colFrom, rowFrom, colTo, rowTo); + // next move + if (theObj = document.getElementById("GameNextMove")) { + if (CurrentVar === 0 && showThisMove + 1 >= StartPly + PlyNumber) { + text = '' + gameResult[currentGame] + ''; + } else if (typeof (Moves[showThisMove + 1]) == "undefined") { + text = ""; + } else { + text = printMoveText(showThisMove + 1, CurrentVar, (CurrentVar !== 0), true, false); + } + theObj.innerHTML = text; + } + + // next variations + if (theObj = document.getElementById("GameNextVariations")) { + text = ''; + if (commentsIntoMoveText) { + var children = childrenVars(showThisMove + 1, CurrentVar); + for (ii = 0; ii < children.length; ii++) { + if (children[ii] !== CurrentVar) { + text += ' ' + printMoveText(showThisMove + 1, children[ii], (children[ii] !== 0), true, false); + } + } + } + theObj.innerHTML = text; + } + + // last move + if (theObj = document.getElementById("GameLastMove")) { + if ((showThisMove >= StartPly) && Moves[showThisMove]) { + text = printMoveText(showThisMove, CurrentVar, (CurrentVar !== 0), true, false); + } else if (showThisMove === StartPly - 1) { + text = '' + (Math.floor((showThisMove + 1) / 2) + 1) + (((showThisMove + 1) % 2) ? "..." : ".") + ''; + } else { + text = ''; + } + theObj.innerHTML = text; + } + + // last variations + if (theObj = document.getElementById("GameLastVariations")) { + text = ''; + if (commentsIntoMoveText) { + var siblings = childrenVars(showThisMove, HistVar[showThisMove]); + for (ii = 0; ii < siblings.length; ii++) { + if (siblings[ii] !== CurrentVar) { + text += ' ' + printMoveText(showThisMove, siblings[ii], (siblings[ii] !== 0), true, false); + } + } + } + theObj.innerHTML = text; + } + + if (showThisMove >= (StartPlyVar[CurrentVar] - 1)) { + moveId = 'Var' + CurrentVar + 'Mv' + (showThisMove + 1); + if (theObj = document.getElementById(moveId)) { + theObj.className = (CurrentVar ? 'variation variationOn' : 'move moveOn') + ' notranslate'; + } + highlightedMoveId = moveId; + + if (highlightOption) { + var colFrom, rowFrom, colTo, rowTo; + if ((showThisMove < StartPly) || HistNull[showThisMove]) { + colFrom = rowFrom = -1; + colTo = rowTo = -1; + } else { + colFrom = HistCol[0][showThisMove] === undefined ? -1 : HistCol[0][showThisMove]; + rowFrom = HistRow[0][showThisMove] === undefined ? -1 : HistRow[0][showThisMove]; + colTo = HistCol[2][showThisMove] === undefined ? -1 : HistCol[2][showThisMove]; + rowTo = HistRow[2][showThisMove] === undefined ? -1 : HistRow[2][showThisMove]; + } + highlightMove(colFrom, rowFrom, colTo, rowTo); + } } - } } function SetHighlightOption(on) { - highlightOption = on; + highlightOption = on; } function SetHighlight(on) { - SetHighlightOption(on); - if (on) { HighlightLastMove(); } - else { highlightMove(-1, -1, -1, -1); } + SetHighlightOption(on); + if (on) { + HighlightLastMove(); + } else { + highlightMove(-1, -1, -1, -1); + } } var colFromHighlighted = -1; var rowFromHighlighted = -1; var colToHighlighted = -1; var rowToHighlighted = -1; + function highlightMove(colFrom, rowFrom, colTo, rowTo) { - highlightSquare(colFromHighlighted, rowFromHighlighted, false); - highlightSquare(colToHighlighted, rowToHighlighted, false); - if ( highlightSquare(colFrom, rowFrom, true) ) { - colFromHighlighted = colFrom; - rowFromHighlighted = rowFrom; - } else { colFromHighlighted = rowFromHighlighted = -1; } - if ( highlightSquare(colTo, rowTo, true) ) { - colToHighlighted = colTo; - rowToHighlighted = rowTo; - } else { colToHighlighted = rowToHighlighted = -1; } + highlightSquare(colFromHighlighted, rowFromHighlighted, false); + highlightSquare(colToHighlighted, rowToHighlighted, false); + if (highlightSquare(colFrom, rowFrom, true)) { + colFromHighlighted = colFrom; + rowFromHighlighted = rowFrom; + } else { + colFromHighlighted = rowFromHighlighted = -1; + } + if (highlightSquare(colTo, rowTo, true)) { + colToHighlighted = colTo; + rowToHighlighted = rowTo; + } else { + colToHighlighted = rowToHighlighted = -1; + } } function highlightSquare(col, row, on) { - if ((col === undefined) || (row === undefined)) { return false; } - if (!SquareOnBoard(col, row)) { return false; } - var trow = IsRotated ? row : 7 - row; - var tcol = IsRotated ? 7 - col : col; - var theObj = document.getElementById('tcol' + tcol + 'trow' + trow); - if (!theObj) { return false; } - if (on) { theObj.className = (trow+tcol)%2 === 0 ? "highlightWhiteSquare" : "highlightBlackSquare"; } - else { theObj.className = (trow+tcol)%2 === 0 ? "whiteSquare" : "blackSquare"; } - return true; + if ((col === undefined) || (row === undefined)) { + return false; + } + if (!SquareOnBoard(col, row)) { + return false; + } + var trow = IsRotated ? row : 7 - row; + var tcol = IsRotated ? 7 - col : col; + var theObj = document.getElementById('tcol' + tcol + 'trow' + trow); + if (!theObj) { + return false; + } + if (on) { + theObj.className = (trow + tcol) % 2 === 0 ? "highlightWhiteSquare" : "highlightBlackSquare"; + } else { + theObj.className = (trow + tcol) % 2 === 0 ? "whiteSquare" : "blackSquare"; + } + return true; } var undoStackMax = 1000; @@ -1552,1180 +2185,1401 @@ var undoStackEnd = 0; var undoRedoInProgress = false; function undoStackReset() { - undoStackGame = new Array(undoStackMax); - undoStackVar = new Array(undoStackMax); - undoStackPly = new Array(undoStackMax); - undoStackStart = undoStackCurrent = undoStackEnd = 0; + undoStackGame = new Array(undoStackMax); + undoStackVar = new Array(undoStackMax); + undoStackPly = new Array(undoStackMax); + undoStackStart = undoStackCurrent = undoStackEnd = 0; } function undoStackStore() { - if (undoRedoInProgress) { return false; } - if ((undoStackStart === undoStackCurrent) || (currentGame !== undoStackGame[undoStackCurrent]) || (CurrentVar !== undoStackVar[undoStackCurrent]) || (CurrentPly !== undoStackPly[undoStackCurrent])) { - undoStackCurrent = (undoStackCurrent + 1) % undoStackMax; - undoStackGame[undoStackCurrent] = currentGame; - undoStackVar[undoStackCurrent] = CurrentVar; - undoStackPly[undoStackCurrent] = CurrentPly; - undoStackEnd = undoStackCurrent; - if (undoStackStart === undoStackCurrent) { undoStackStart = (undoStackStart + 1) % undoStackMax; } - } - return true; + if (undoRedoInProgress) { + return false; + } + if ((undoStackStart === undoStackCurrent) || (currentGame !== undoStackGame[undoStackCurrent]) || (CurrentVar !== undoStackVar[undoStackCurrent]) || (CurrentPly !== undoStackPly[undoStackCurrent])) { + undoStackCurrent = (undoStackCurrent + 1) % undoStackMax; + undoStackGame[undoStackCurrent] = currentGame; + undoStackVar[undoStackCurrent] = CurrentVar; + undoStackPly[undoStackCurrent] = CurrentPly; + undoStackEnd = undoStackCurrent; + if (undoStackStart === undoStackCurrent) { + undoStackStart = (undoStackStart + 1) % undoStackMax; + } + } + return true; } function undoStackUndo() { - if ((undoStackCurrent - 1 + undoStackMax) % undoStackMax === undoStackStart) { return false; } - undoRedoInProgress = true; - undoStackCurrent = (undoStackCurrent - 1 + undoStackMax) % undoStackMax; - if (undoStackGame[undoStackCurrent] !== currentGame) { Init(undoStackGame[undoStackCurrent]); } - GoToMove(undoStackPly[undoStackCurrent], undoStackVar[undoStackCurrent]); - undoRedoInProgress = false; - return true; + if ((undoStackCurrent - 1 + undoStackMax) % undoStackMax === undoStackStart) { + return false; + } + undoRedoInProgress = true; + undoStackCurrent = (undoStackCurrent - 1 + undoStackMax) % undoStackMax; + if (undoStackGame[undoStackCurrent] !== currentGame) { + Init(undoStackGame[undoStackCurrent]); + } + GoToMove(undoStackPly[undoStackCurrent], undoStackVar[undoStackCurrent]); + undoRedoInProgress = false; + return true; } function undoStackRedo() { - if (undoStackCurrent === undoStackEnd) { return false; } - undoRedoInProgress = true; - undoStackCurrent = (undoStackCurrent + 1) % undoStackMax; - if (undoStackGame[undoStackCurrent] !== currentGame) { Init(undoStackGame[undoStackCurrent]); } - GoToMove(undoStackPly[undoStackCurrent], undoStackVar[undoStackCurrent]); - undoRedoInProgress = false; - return true; + if (undoStackCurrent === undoStackEnd) { + return false; + } + undoRedoInProgress = true; + undoStackCurrent = (undoStackCurrent + 1) % undoStackMax; + if (undoStackGame[undoStackCurrent] !== currentGame) { + Init(undoStackGame[undoStackCurrent]); + } + GoToMove(undoStackPly[undoStackCurrent], undoStackVar[undoStackCurrent]); + undoRedoInProgress = false; + return true; } function fixCommonPgnMistakes(text) { - text = text.replace(/[\u00A0\u180E\u2000-\u200A\u202F\u205F\u3000]/g," "); // some spaces to plain space - text = text.replace(/\u00BD/g,"1/2"); // "half fraction" to "1/2" - text = text.replace(/[\u2010-\u2015]/g,"-"); // "hyphens" to "-" - text = text.replace(/\u2024/g,"."); // "one dot leader" to "." - text = text.replace(/[\u2025-\u2026]/g,"..."); // "two dot leader" and "ellipsis" to "..." - text = text.replace(/\\"/g,"'"); // fix [Opening "Queen\"s gambit"] - return text; + text = text.replace(/[\u00A0\u180E\u2000-\u200A\u202F\u205F\u3000]/g, " "); // some spaces to plain space + text = text.replace(/\u00BD/g, "1/2"); // "half fraction" to "1/2" + text = text.replace(/[\u2010-\u2015]/g, "-"); // "hyphens" to "-" + text = text.replace(/\u2024/g, "."); // "one dot leader" to "." + text = text.replace(/[\u2025-\u2026]/g, "..."); // "two dot leader" and "ellipsis" to "..." + text = text.replace(/\\"/g, "'"); // fix [Opening "Queen\"s gambit"] + return text; } function fullPgnGame(gameNum) { - var res = pgnHeader[gameNum] ? pgnHeader[gameNum].replace(/^[^[]*/g, "") : ""; - res = res.replace(/\[\s*(\w+)\s*"([^"]*)"\s*\][^[]*/g, '[$1 "$2"]\n'); - res += "\n"; - res += pgnGame[gameNum] ? pgnGame[gameNum].replace(/(^[\s]*|[\s]*$)/g, "") : ""; - return res; + var res = pgnHeader[gameNum] ? pgnHeader[gameNum].replace(/^[^[]*/g, "") : ""; + res = res.replace(/\[\s*(\w+)\s*"([^"]*)"\s*\][^[]*/g, '[$1 "$2"]\n'); + res += "\n"; + res += pgnGame[gameNum] ? pgnGame[gameNum].replace(/(^[\s]*|[\s]*$)/g, "") : ""; + return res; } function pgnGameFromPgnText(pgnText) { - var newNumGames, headMatch, prevHead, newHead, startNew, afterNew, lastOpen, checkedGame, validHead; + var newNumGames, headMatch, prevHead, newHead, startNew, afterNew, lastOpen, checkedGame, validHead; - pgnText = simpleHtmlentities(fixCommonPgnMistakes(pgnText)); + pgnText = simpleHtmlentities(fixCommonPgnMistakes(pgnText)); - // PGN standard: ignore lines starting with % - pgnText = pgnText.replace(/(^|\n)%.*(\n|$)/g, "\n"); + // PGN standard: ignore lines starting with % + pgnText = pgnText.replace(/(^|\n)%.*(\n|$)/g, "\n"); - newNumGames = 0; - checkedGame = ""; - while (headMatch = pgnHeaderBlockRegExp.exec(pgnText)) { - newHead = headMatch[0]; - startNew = pgnText.indexOf(newHead); - afterNew = startNew + newHead.length; - if (prevHead) { - checkedGame += pgnText.slice(0, startNew); - validHead = ((lastOpen = checkedGame.lastIndexOf("{")) < 0) || (checkedGame.lastIndexOf("}")) > lastOpen; - if (validHead) { - pgnHeader[newNumGames] = prevHead; - pgnGame[newNumGames++] = checkedGame; - checkedGame = ""; - } else { - checkedGame += newHead; - } - } else { - validHead = true; + newNumGames = 0; + checkedGame = ""; + while (headMatch = pgnHeaderBlockRegExp.exec(pgnText)) { + newHead = headMatch[0]; + startNew = pgnText.indexOf(newHead); + afterNew = startNew + newHead.length; + if (prevHead) { + checkedGame += pgnText.slice(0, startNew); + validHead = ((lastOpen = checkedGame.lastIndexOf("{")) < 0) || (checkedGame.lastIndexOf("}")) > lastOpen; + if (validHead) { + pgnHeader[newNumGames] = prevHead; + pgnGame[newNumGames++] = checkedGame; + checkedGame = ""; + } else { + checkedGame += newHead; + } + } else { + validHead = true; + } + if (validHead) { + prevHead = newHead; + } + pgnText = pgnText.slice(afterNew); + } + if (prevHead) { + pgnHeader[newNumGames] = prevHead; + checkedGame += pgnText; + pgnGame[newNumGames++] = checkedGame; } - if (validHead) { prevHead = newHead; } - pgnText = pgnText.slice(afterNew); - } - if (prevHead) { - pgnHeader[newNumGames] = prevHead; - checkedGame += pgnText; - pgnGame[newNumGames++] = checkedGame; - } - if (newNumGames === 0) { return false; } - numberOfGames = newNumGames; - return true; + if (newNumGames === 0) { + return false; + } + numberOfGames = newNumGames; + return true; } function pgnGameFromHttpRequest(httpResponseData) { - // process here any special file types, for instance zipfiles: - // if (pgnUrl && pgnUrl.replace(/[?#].*/, "").match(/\.zip$/i)) { return pgnGameFromPgnText(unzipPgnFiles(httpResponseData)); } - // remember to fix function loadPgnFromPgnUrl() for binary data + // process here any special file types, for instance zipfiles: + // if (pgnUrl && pgnUrl.replace(/[?#].*/, "").match(/\.zip$/i)) { return pgnGameFromPgnText(unzipPgnFiles(httpResponseData)); } + // remember to fix function loadPgnFromPgnUrl() for binary data - return pgnGameFromPgnText(httpResponseData); + return pgnGameFromPgnText(httpResponseData); } var http_request_last_processed_id = 0; + function updatePgnFromHttpRequest(this_http_request, this_http_request_id) { - var res = LOAD_PGN_FAIL; + var res = LOAD_PGN_FAIL; - if (this_http_request.readyState != 4) { return; } - - if (this_http_request_id < http_request_last_processed_id) { return; } - else { http_request_last_processed_id = this_http_request_id; } - - // patch: enable loading local PGN files on some browsers by adding: || (this_http_request.status === 0) - if ((this_http_request.status == 200) || (this_http_request.status == 304)) { - - if (this_http_request.status == 304) { - if (LiveBroadcastDelay > 0) { - res = LOAD_PGN_UNMODIFIED; - } else { - myAlert('error: unmodified PGN URL when not in live mode'); - } - } else if (!this_http_request.responseText) { - myAlert('error: no data received from PGN URL\n' + pgnUrl, true); - } else if (!pgnGameFromHttpRequest(this_http_request.responseText)) { - myAlert('error: no games found at PGN URL\n' + pgnUrl, true); - } else { - if (LiveBroadcastDelay > 0) { - LiveBroadcastLastReceivedLocal = (new Date()).toLocaleString(); - if (LiveBroadcastLastModifiedHeader = this_http_request.getResponseHeader("Last-Modified")) { - LiveBroadcastLastModified = new Date(LiveBroadcastLastModifiedHeader); - } else { LiveBroadcastLastModified_Reset(); } - } - res = LOAD_PGN_OK; + if (this_http_request.readyState != 4) { + return; } - } else { - myAlert('error: failed reading PGN URL\n' + pgnUrl, true); - } + if (this_http_request_id < http_request_last_processed_id) { + return; + } else { + http_request_last_processed_id = this_http_request_id; + } - if (LiveBroadcastDemo && (res == LOAD_PGN_UNMODIFIED)) { - res = LOAD_PGN_OK; - } + // patch: enable loading local PGN files on some browsers by adding: || (this_http_request.status === 0) + if ((this_http_request.status == 200) || (this_http_request.status == 304)) { - loadPgnCheckingLiveStatus(res); + if (this_http_request.status == 304) { + if (LiveBroadcastDelay > 0) { + res = LOAD_PGN_UNMODIFIED; + } else { + myAlert('error: unmodified PGN URL when not in live mode'); + } + } else if (!this_http_request.responseText) { + myAlert('error: no data received from PGN URL\n' + pgnUrl, true); + } else if (!pgnGameFromHttpRequest(this_http_request.responseText)) { + myAlert('error: no games found at PGN URL\n' + pgnUrl, true); + } else { + if (LiveBroadcastDelay > 0) { + LiveBroadcastLastReceivedLocal = (new Date()).toLocaleString(); + if (LiveBroadcastLastModifiedHeader = this_http_request.getResponseHeader("Last-Modified")) { + LiveBroadcastLastModified = new Date(LiveBroadcastLastModifiedHeader); + } else { + LiveBroadcastLastModified_Reset(); + } + } + res = LOAD_PGN_OK; + } + + } else { + myAlert('error: failed reading PGN URL\n' + pgnUrl, true); + } + + if (LiveBroadcastDemo && (res == LOAD_PGN_UNMODIFIED)) { + res = LOAD_PGN_OK; + } + + loadPgnCheckingLiveStatus(res); } var LOAD_PGN_FAIL = 0; var LOAD_PGN_OK = 1; var LOAD_PGN_UNMODIFIED = 2; + function loadPgnCheckingLiveStatus(res) { - switch (res) { + switch (res) { - case LOAD_PGN_OK: - if (LiveBroadcastDelay > 0) { - firstStart = true; - var oldParseLastMoveError = ParseLastMoveError; - if (!LiveBroadcastStarted) { - LiveBroadcastStarted = true; - } else { - var oldWhite = gameWhite[currentGame]; - var oldBlack = gameBlack[currentGame]; - var oldEvent = gameEvent[currentGame]; - var oldRound = gameRound[currentGame]; - var oldSite = gameSite[currentGame]; - var oldDate = gameDate[currentGame]; + case LOAD_PGN_OK: + if (LiveBroadcastDelay > 0) { + firstStart = true; + var oldParseLastMoveError = ParseLastMoveError; + if (!LiveBroadcastStarted) { + LiveBroadcastStarted = true; + } else { + var oldWhite = gameWhite[currentGame]; + var oldBlack = gameBlack[currentGame]; + var oldEvent = gameEvent[currentGame]; + var oldRound = gameRound[currentGame]; + var oldSite = gameSite[currentGame]; + var oldDate = gameDate[currentGame]; - initialGame = currentGame + 1; + initialGame = currentGame + 1; - LiveBroadcastOldCurrentVar = CurrentVar; - LiveBroadcastOldCurrentPly = CurrentPly; - LiveBroadcastOldCurrentPlyLast = (CurrentVar === 0 && CurrentPly === StartPlyVar[0] + PlyNumberVar[0]); + LiveBroadcastOldCurrentVar = CurrentVar; + LiveBroadcastOldCurrentPly = CurrentPly; + LiveBroadcastOldCurrentPlyLast = (CurrentVar === 0 && CurrentPly === StartPlyVar[0] + PlyNumberVar[0]); - var oldAutoplay = isAutoPlayOn; - if (isAutoPlayOn) { SetAutoPlay(false); } + var oldAutoplay = isAutoPlayOn; + if (isAutoPlayOn) { + SetAutoPlay(false); + } - LoadGameHeaders(); - LiveBroadcastFoundOldGame = false; - for (var ii=0; ii 0) { - if (LiveBroadcastFoundOldGame) { - initialHalfmove = oldInitialHalfmove; - initialVariation = oldInitialVariation; - } - checkLiveBroadcastStatus(); - } + if (LiveBroadcastDelay > 0) { + if (LiveBroadcastFoundOldGame) { + initialHalfmove = oldInitialHalfmove; + initialVariation = oldInitialVariation; + } + checkLiveBroadcastStatus(); + } - customFunctionOnPgnTextLoad(); + customFunctionOnPgnTextLoad(); - if (LiveBroadcastDelay > 0) { - if (LiveBroadcastFoundOldGame) { - if (LiveBroadcastSteppingMode) { - if (oldAutoplay || LiveBroadcastOldCurrentPlyLast || oldParseLastMoveError) { SetAutoPlay(true); } - } else { - if (oldAutoplay) { SetAutoPlay(true); } - } - } - } + if (LiveBroadcastDelay > 0) { + if (LiveBroadcastFoundOldGame) { + if (LiveBroadcastSteppingMode) { + if (oldAutoplay || LiveBroadcastOldCurrentPlyLast || oldParseLastMoveError) { + SetAutoPlay(true); + } + } else { + if (oldAutoplay) { + SetAutoPlay(true); + } + } + } + } - break; + break; - case LOAD_PGN_UNMODIFIED: - if (LiveBroadcastDelay > 0) { - checkLiveBroadcastStatus(); - } - break; + case LOAD_PGN_UNMODIFIED: + if (LiveBroadcastDelay > 0) { + checkLiveBroadcastStatus(); + } + break; - case LOAD_PGN_FAIL: - default: - if (LiveBroadcastDelay === 0) { - pgnGameFromPgnText(alertPgn); - undoStackReset(); - Init(); - customFunctionOnPgnTextLoad(); - } else { // live broadcast: wait for live show start - if (!LiveBroadcastStarted) { - pgnGameFromPgnText(LiveBroadcastPlaceholderPgn); - firstStart = true; - undoStackReset(); - Init(); - checkLiveBroadcastStatus(); - customFunctionOnPgnTextLoad(); - } else { checkLiveBroadcastStatus(); } - } - break; + case LOAD_PGN_FAIL: + default: + if (LiveBroadcastDelay === 0) { + pgnGameFromPgnText(alertPgn); + undoStackReset(); + Init(); + customFunctionOnPgnTextLoad(); + } else { // live broadcast: wait for live show start + if (!LiveBroadcastStarted) { + pgnGameFromPgnText(LiveBroadcastPlaceholderPgn); + firstStart = true; + undoStackReset(); + Init(); + checkLiveBroadcastStatus(); + customFunctionOnPgnTextLoad(); + } else { + checkLiveBroadcastStatus(); + } + } + break; - } + } - if (LiveBroadcastDelay > 0) { restartLiveBroadcastTimeout(); } + if (LiveBroadcastDelay > 0) { + restartLiveBroadcastTimeout(); + } } var http_request_last_id = 0; + function loadPgnFromPgnUrl(pgnUrl) { - LiveBroadcastLastRefreshedLocal = (new Date()).toLocaleString(); + LiveBroadcastLastRefreshedLocal = (new Date()).toLocaleString(); - try { - var http_request = new XMLHttpRequest(); - if (http_request.overrideMimeType) { - // patch: pgn encoding: amend the following line to match the expected encoding of the PGN file if charachters beyond the basic 128 ascii set are not displayed correctly - http_request.overrideMimeType("text/plain"); // this assumes the PGN file is encoded as unicode UTF-8 - // http_request.overrideMimeType("text/plain; charset=ISO-8859-15"); // this has been reported to work with some files created by the DGT live boards software - // http_request.overrideMimeType("text/plain; charset=x-user-defined"); // this works with a binary file, such as a zipfile, but would need further processing + try { + var http_request = new XMLHttpRequest(); + if (http_request.overrideMimeType) { + // patch: pgn encoding: amend the following line to match the expected encoding of the PGN file if charachters beyond the basic 128 ascii set are not displayed correctly + http_request.overrideMimeType("text/plain"); // this assumes the PGN file is encoded as unicode UTF-8 + // http_request.overrideMimeType("text/plain; charset=ISO-8859-15"); // this has been reported to work with some files created by the DGT live boards software + // http_request.overrideMimeType("text/plain; charset=x-user-defined"); // this works with a binary file, such as a zipfile, but would need further processing + } + } catch (e) { + myAlert('error: failed creating XMLHttpRequest for PGN URL\n' + pgnUrl, true); + loadPgnCheckingLiveStatus(LOAD_PGN_FAIL); + return false; } - } catch(e) { - myAlert('error: failed creating XMLHttpRequest for PGN URL\n' + pgnUrl, true); - loadPgnCheckingLiveStatus(LOAD_PGN_FAIL); - return false; - } - var http_request_id = http_request_last_id++; - http_request.onreadystatechange = function () { updatePgnFromHttpRequest(http_request, http_request_id); }; + var http_request_id = http_request_last_id++; + http_request.onreadystatechange = function () { + updatePgnFromHttpRequest(http_request, http_request_id); + }; - try { - var randomizer = ""; - // anti-caching #1 - if ((LiveBroadcastDelay > 0) && (pgnUrl.indexOf("?") == -1) && (pgnUrl.indexOf("#") == -1)) { - randomizer = "?noCache=" + (0x1000000000 + Math.floor((Math.random() * 0xF000000000))).toString(16).toUpperCase(); + try { + var randomizer = ""; + // anti-caching #1 + if ((LiveBroadcastDelay > 0) && (pgnUrl.indexOf("?") == -1) && (pgnUrl.indexOf("#") == -1)) { + randomizer = "?noCache=" + (0x1000000000 + Math.floor((Math.random() * 0xF000000000))).toString(16).toUpperCase(); + } + http_request.open("GET", pgnUrl + randomizer); + // anti-caching #2 + if (LiveBroadcastDelay > 0) { + http_request.setRequestHeader("If-Modified-Since", LiveBroadcastLastModifiedHeader); + } + http_request.send(null); + } catch (e) { + myAlert('error: failed sending XMLHttpRequest for PGN URL\n' + pgnUrl, true); + return false; } - http_request.open("GET", pgnUrl + randomizer); - // anti-caching #2 - if (LiveBroadcastDelay > 0) { - http_request.setRequestHeader( "If-Modified-Since", LiveBroadcastLastModifiedHeader ); - } - http_request.send(null); - } catch(e) { - myAlert('error: failed sending XMLHttpRequest for PGN URL\n' + pgnUrl, true); - return false; - } - return true; + return true; } function SetPgnUrl(url) { - pgnUrl = url; + pgnUrl = url; } function LiveBroadcastLastModified_Reset() { - LiveBroadcastLastModified = new Date(0); - LiveBroadcastLastModifiedHeader = LiveBroadcastLastModified.toUTCString(); + LiveBroadcastLastModified = new Date(0); + LiveBroadcastLastModifiedHeader = LiveBroadcastLastModified.toUTCString(); } function LiveBroadcastLastReceivedLocal_Reset() { - LiveBroadcastLastReceivedLocal = 'unavailable'; + LiveBroadcastLastReceivedLocal = 'unavailable'; } function LiveBroadcastLastModified_ServerTime() { - return LiveBroadcastLastModified.getTime() === 0 ? 'unavailable' : LiveBroadcastLastModifiedHeader; + return LiveBroadcastLastModified.getTime() === 0 ? 'unavailable' : LiveBroadcastLastModifiedHeader; } function pauseLiveBroadcast() { - if ((LiveBroadcastDelay === 0) || (LiveBroadcastPaused)) { return; } - LiveBroadcastPaused = true; - clearTimeout(LiveBroadcastInterval); - LiveBroadcastInterval = null; - LiveBroadcastTicker--; - checkLiveBroadcastStatus(); - LiveBroadcastTicker++; + if ((LiveBroadcastDelay === 0) || (LiveBroadcastPaused)) { + return; + } + LiveBroadcastPaused = true; + clearTimeout(LiveBroadcastInterval); + LiveBroadcastInterval = null; + LiveBroadcastTicker--; + checkLiveBroadcastStatus(); + LiveBroadcastTicker++; } function restartLiveBroadcast() { - if (LiveBroadcastDelay === 0) { return; } - LiveBroadcastPaused = false; - refreshPgnSource(); + if (LiveBroadcastDelay === 0) { + return; + } + LiveBroadcastPaused = false; + refreshPgnSource(); } function checkLiveBroadcastStatus() { - if (LiveBroadcastDelay === 0) { return; } + if (LiveBroadcastDelay === 0) { + return; + } - var theTitle, theHTML, theObj, ii; + var theTitle, theHTML, theObj, ii; - // broadcast started yet? - if (LiveBroadcastStarted === false || typeof(pgnHeader) == "undefined" || (numberOfGames == 1 && gameEvent[0] == LiveBroadcastPlaceholderEvent)) { - // no - LiveBroadcastEnded = false; - LiveBroadcastGamesRunning = 0; - theTitle = "live broadcast yet to start"; - } else { - // yes - var lbgr = 0, lbga = 0; - for (ii=0; ii= 0) { lbga++; if (!pgnGame[ii].match(/^\s*\*?\s*$/)) { lbgr++; } } } - LiveBroadcastEnded = ((lbga === 0) && (!LiveBroadcastEndlessMode)); - LiveBroadcastGamesRunning = lbgr; - theTitle = LiveBroadcastEnded ? "live broadcast ended" : LiveBroadcastPaused ? "live broadcast paused" : lbgr + " live game" + (lbgr == 1 ? "" : "s") + " out of " + numberOfGames; - } - theHTML = LiveBroadcastEnded ? "#" : LiveBroadcastPaused ? "+" : "="; - theHTML = (LiveBroadcastTicker % 4 === 3 ? theHTML : " ") + (LiveBroadcastTicker % 2 === 0 ? theHTML : " ") + (LiveBroadcastTicker % 4 === 1 ? theHTML : " "); - theHTML = LiveBroadcastGamesRunning + "" + theHTML + "" + numberOfGames; - theHTML = "" + theHTML + ""; + // broadcast started yet? + if (LiveBroadcastStarted === false || typeof (pgnHeader) == "undefined" || (numberOfGames == 1 && gameEvent[0] == LiveBroadcastPlaceholderEvent)) { + // no + LiveBroadcastEnded = false; + LiveBroadcastGamesRunning = 0; + theTitle = "live broadcast yet to start"; + } else { + // yes + var lbgr = 0, lbga = 0; + for (ii = 0; ii < numberOfGames; ii++) { + if (gameResult[ii].indexOf('*') >= 0) { + lbga++; + if (!pgnGame[ii].match(/^\s*\*?\s*$/)) { + lbgr++; + } + } + } + LiveBroadcastEnded = ((lbga === 0) && (!LiveBroadcastEndlessMode)); + LiveBroadcastGamesRunning = lbgr; + theTitle = LiveBroadcastEnded ? "live broadcast ended" : LiveBroadcastPaused ? "live broadcast paused" : lbgr + " live game" + (lbgr == 1 ? "" : "s") + " out of " + numberOfGames; + } + theHTML = LiveBroadcastEnded ? "#" : LiveBroadcastPaused ? "+" : "="; + theHTML = (LiveBroadcastTicker % 4 === 3 ? theHTML : " ") + (LiveBroadcastTicker % 2 === 0 ? theHTML : " ") + (LiveBroadcastTicker % 4 === 1 ? theHTML : " "); + theHTML = LiveBroadcastGamesRunning + "" + theHTML + "" + numberOfGames; + theHTML = "" + theHTML + ""; - if (theObj = document.getElementById("GameLiveStatus")) { - theObj.innerHTML = theHTML; - theObj.title = theTitle; - } + if (theObj = document.getElementById("GameLiveStatus")) { + theObj.innerHTML = theHTML; + theObj.title = theTitle; + } - if (theObj = document.getElementById("GameLiveLastRefreshed")) { theObj.innerHTML = LiveBroadcastLastRefreshedLocal; } - if (theObj = document.getElementById("GameLiveLastReceived")) { theObj.innerHTML = LiveBroadcastLastReceivedLocal; } - if (theObj = document.getElementById("GameLiveLastModifiedServer")) { theObj.innerHTML = LiveBroadcastLastModified_ServerTime(); } + if (theObj = document.getElementById("GameLiveLastRefreshed")) { + theObj.innerHTML = LiveBroadcastLastRefreshedLocal; + } + if (theObj = document.getElementById("GameLiveLastReceived")) { + theObj.innerHTML = LiveBroadcastLastReceivedLocal; + } + if (theObj = document.getElementById("GameLiveLastModifiedServer")) { + theObj.innerHTML = LiveBroadcastLastModified_ServerTime(); + } - customFunctionOnCheckLiveBroadcastStatus(); + customFunctionOnCheckLiveBroadcastStatus(); } function restartLiveBroadcastTimeout() { - if (LiveBroadcastDelay === 0) { return; } - if (LiveBroadcastInterval) { clearTimeout(LiveBroadcastInterval); LiveBroadcastInterval = null; } - if ((!LiveBroadcastEnded) && (!LiveBroadcastPaused)) { - LiveBroadcastInterval = setTimeout("refreshPgnSource()", LiveBroadcastDelay * 60000); - } - LiveBroadcastTicker++; + if (LiveBroadcastDelay === 0) { + return; + } + if (LiveBroadcastInterval) { + clearTimeout(LiveBroadcastInterval); + LiveBroadcastInterval = null; + } + if ((!LiveBroadcastEnded) && (!LiveBroadcastPaused)) { + LiveBroadcastInterval = setTimeout("refreshPgnSource()", LiveBroadcastDelay * 60000); + } + LiveBroadcastTicker++; } var LiveBroadcastFoundOldGame = false; var LiveBroadcastOldCurrentVar; var LiveBroadcastOldCurrentPly; var LiveBroadcastOldCurrentPlyLast = false; -function refreshPgnSource() { - if (LiveBroadcastDelay === 0) { return; } - if (LiveBroadcastInterval) { clearTimeout(LiveBroadcastInterval); LiveBroadcastInterval = null; } - if (LiveBroadcastDemo) { - var newPly, addedPly = 0; - for (var ii=0; ii 0) { LiveBroadcastLastReceivedLocal = (new Date()).toLocaleString(); } - } - if (pgnUrl) { - loadPgnFromPgnUrl(pgnUrl); - } else if ( document.getElementById("pgnText") ) { - loadPgnFromTextarea("pgnText"); - } else { - pgnGameFromPgnText(alertPgn); - undoStackReset(); - Init(); - customFunctionOnPgnTextLoad(); - myAlert('error: missing PGN URL location and pgnText object in the HTML file', true); - } +function refreshPgnSource() { + if (LiveBroadcastDelay === 0) { + return; + } + if (LiveBroadcastInterval) { + clearTimeout(LiveBroadcastInterval); + LiveBroadcastInterval = null; + } + if (LiveBroadcastDemo) { + var newPly, addedPly = 0; + for (var ii = 0; ii < numberOfGames; ii++) { + // 5% 15% 40% + newPly = [3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1][Math.floor(20 * Math.random())] || 0; + if (gameDemoMaxPly[ii] <= gameDemoLength[ii]) { + gameDemoMaxPly[ii] += newPly; + addedPly += newPly; + } + } + if (addedPly > 0) { + LiveBroadcastLastReceivedLocal = (new Date()).toLocaleString(); + } + } + + if (pgnUrl) { + loadPgnFromPgnUrl(pgnUrl); + } else if (document.getElementById("pgnText")) { + loadPgnFromTextarea("pgnText"); + } else { + pgnGameFromPgnText(alertPgn); + undoStackReset(); + Init(); + customFunctionOnPgnTextLoad(); + myAlert('error: missing PGN URL location and pgnText object in the HTML file', true); + } } function loadPgnFromTextarea(textareaId) { - var res = LOAD_PGN_FAIL, text, theObj; + var res = LOAD_PGN_FAIL, text, theObj; - LiveBroadcastLastRefreshedLocal = (new Date()).toLocaleString(); + LiveBroadcastLastRefreshedLocal = (new Date()).toLocaleString(); - if (!(theObj = document.getElementById(textareaId))) { - myAlert('error: missing ' + textareaId + ' textarea object in the HTML file', true); - } else { - if (document.getElementById(textareaId).tagName.toLowerCase() == "textarea") { - text = document.getElementById(textareaId).value; - } else { // compatibility with pgn4web up to 1.77: used for pgnText - text = document.getElementById(textareaId).innerHTML; - // fixes browser issue removing \n from innerHTML - if (text.indexOf('\n') < 0) { text = text.replace(/((\[[^\[\]]*\]\s*)+)/g, "\n$1\n"); } - // fixes browser issue replacing quotes with " - if (text.indexOf('"') < 0) { text = text.replace(/(")/g, '"'); } - } - - // no header: add emptyPgnHeader - if (pgnHeaderTagRegExp.test(text) === false) { text = emptyPgnHeader + "\n" + text; } - - if ( pgnGameFromPgnText(text) ) { - res = LOAD_PGN_OK; - LiveBroadcastLastReceivedLocal = (new Date()).toLocaleString(); + if (!(theObj = document.getElementById(textareaId))) { + myAlert('error: missing ' + textareaId + ' textarea object in the HTML file', true); } else { - myAlert('error: no games found in ' + textareaId + ' object in the HTML file'); - } - } + if (document.getElementById(textareaId).tagName.toLowerCase() == "textarea") { + text = document.getElementById(textareaId).value; + } else { // compatibility with pgn4web up to 1.77: used for pgnText + text = document.getElementById(textareaId).innerHTML; + // fixes browser issue removing \n from innerHTML + if (text.indexOf('\n') < 0) { + text = text.replace(/((\[[^\[\]]*\]\s*)+)/g, "\n$1\n"); + } + // fixes browser issue replacing quotes with " + if (text.indexOf('"') < 0) { + text = text.replace(/(")/g, '"'); + } + } - loadPgnCheckingLiveStatus(res); + // no header: add emptyPgnHeader + if (pgnHeaderTagRegExp.test(text) === false) { + text = emptyPgnHeader + "\n" + text; + } + + if (pgnGameFromPgnText(text)) { + res = LOAD_PGN_OK; + LiveBroadcastLastReceivedLocal = (new Date()).toLocaleString(); + } else { + myAlert('error: no games found in ' + textareaId + ' object in the HTML file'); + } + } + + loadPgnCheckingLiveStatus(res); } function createBoard() { - if (pgnUrl) { - loadPgnFromPgnUrl(pgnUrl); - } else if ( document.getElementById("pgnText") ) { - loadPgnFromTextarea("pgnText"); - } else { - pgnGameFromPgnText(alertPgn); - undoStackReset(); - Init(); - customFunctionOnPgnTextLoad(); - myAlert('error: missing PGN URL location or pgnText in the HTML file', true); - } + if (pgnUrl) { + loadPgnFromPgnUrl(pgnUrl); + } else if (document.getElementById("pgnText")) { + loadPgnFromTextarea("pgnText"); + } else { + pgnGameFromPgnText(alertPgn); + undoStackReset(); + Init(); + customFunctionOnPgnTextLoad(); + myAlert('error: missing PGN URL location or pgnText in the HTML file', true); + } } function setCurrentGameFromInitialGame() { - switch (initialGame) { - case "first": - currentGame = 0; - break; - case "last": - currentGame = numberOfGames - 1; - break; - case "random": - currentGame = Math.floor(Math.random()*numberOfGames); - break; - default: - if (isNaN(parseInt(initialGame,10))) { - currentGame = gameNumberSearchPgn(initialGame, false, true); - if (!currentGame) { currentGame = 0; } - } else { - initialGame = parseInt(initialGame,10); - initialGame = initialGame < 0 ? -Math.floor(-initialGame) : Math.floor(initialGame); - if (initialGame < -numberOfGames) { currentGame = 0; } - else if (initialGame < 0) { currentGame = numberOfGames + initialGame; } - else if (initialGame === 0) { currentGame = Math.floor(Math.random()*numberOfGames); } - else if (initialGame <= numberOfGames) { currentGame = (initialGame - 1); } - else { currentGame = numberOfGames - 1; } - } - break; - } + switch (initialGame) { + case "first": + currentGame = 0; + break; + case "last": + currentGame = numberOfGames - 1; + break; + case "random": + currentGame = Math.floor(Math.random() * numberOfGames); + break; + default: + if (isNaN(parseInt(initialGame, 10))) { + currentGame = gameNumberSearchPgn(initialGame, false, true); + if (!currentGame) { + currentGame = 0; + } + } else { + initialGame = parseInt(initialGame, 10); + initialGame = initialGame < 0 ? -Math.floor(-initialGame) : Math.floor(initialGame); + if (initialGame < -numberOfGames) { + currentGame = 0; + } else if (initialGame < 0) { + currentGame = numberOfGames + initialGame; + } else if (initialGame === 0) { + currentGame = Math.floor(Math.random() * numberOfGames); + } else if (initialGame <= numberOfGames) { + currentGame = (initialGame - 1); + } else { + currentGame = numberOfGames - 1; + } + } + break; + } } function GoToInitialHalfmove() { - var iv, ih; - if (initialVariation < 0) { iv = Math.max(numberOfVars + initialVariations, 0); } - else { iv = Math.min(initialVariation, numberOfVars - 1); } + var iv, ih; + if (initialVariation < 0) { + iv = Math.max(numberOfVars + initialVariations, 0); + } else { + iv = Math.min(initialVariation, numberOfVars - 1); + } - switch (initialHalfmove) { - case "start": - GoToMove((StartPlyVar[iv] + (iv ? 1 : 0)), iv); - break; - case "end": - GoToMove(StartPlyVar[iv] + PlyNumberVar[iv], iv); - break; - case "random": - GoToMove((StartPlyVar[iv] + (iv ? 1 : 0)) + Math.floor(Math.random()*(StartPlyVar[iv] + PlyNumberVar[iv])), iv); - break; - case "comment": - case "variation": - GoToMove((StartPlyVar[iv] + (iv ? 1 : 0)), iv); - MoveToNextComment(initialHalfmove == "variation"); - break; - default: - if (isNaN(initialHalfmove = parseInt(initialHalfmove, 10))) { initialHalfmove = 0; } - if (initialHalfmove < 0) { ih = Math.max(StartPlyVar[iv] + PlyNumberVar[iv] + 1 + initialHalfmove, StartPly); } - else { ih = Math.min(initialHalfmove, StartPlyVar[iv] + PlyNumberVar[iv]); } - GoToMove(ih, iv); - break; - } + switch (initialHalfmove) { + case "start": + GoToMove((StartPlyVar[iv] + (iv ? 1 : 0)), iv); + break; + case "end": + GoToMove(StartPlyVar[iv] + PlyNumberVar[iv], iv); + break; + case "random": + GoToMove((StartPlyVar[iv] + (iv ? 1 : 0)) + Math.floor(Math.random() * (StartPlyVar[iv] + PlyNumberVar[iv])), iv); + break; + case "comment": + case "variation": + GoToMove((StartPlyVar[iv] + (iv ? 1 : 0)), iv); + MoveToNextComment(initialHalfmove == "variation"); + break; + default: + if (isNaN(initialHalfmove = parseInt(initialHalfmove, 10))) { + initialHalfmove = 0; + } + if (initialHalfmove < 0) { + ih = Math.max(StartPlyVar[iv] + PlyNumberVar[iv] + 1 + initialHalfmove, StartPly); + } else { + ih = Math.min(initialHalfmove, StartPlyVar[iv] + PlyNumberVar[iv]); + } + GoToMove(ih, iv); + break; + } } function Init(nextGame) { - if (nextGame !== undefined) { - if ((!isNaN(nextGame)) && (nextGame >= 0) && (nextGame < numberOfGames)) { - currentGame = parseInt(nextGame,10); - } else { return; } - } + if (nextGame !== undefined) { + if ((!isNaN(nextGame)) && (nextGame >= 0) && (nextGame < numberOfGames)) { + currentGame = parseInt(nextGame, 10); + } else { + return; + } + } - if (isAutoPlayOn) { SetAutoPlay(false); } + if (isAutoPlayOn) { + SetAutoPlay(false); + } - InitImages(); - if (firstStart) { - LoadGameHeaders(); - setCurrentGameFromInitialGame(); - } + InitImages(); + if (firstStart) { + LoadGameHeaders(); + setCurrentGameFromInitialGame(); + } - if ((gameSetUp[currentGame] !== undefined) && (gameSetUp[currentGame] != "1")) { InitFEN(); } - else { InitFEN(gameFEN[currentGame]); } + if ((gameSetUp[currentGame] !== undefined) && (gameSetUp[currentGame] != "1")) { + InitFEN(); + } else { + InitFEN(gameFEN[currentGame]); + } - OpenGame(currentGame); + OpenGame(currentGame); - CurrentPly = StartPly; - if (firstStart || alwaysInitialHalfmove) { - GoToInitialHalfmove(); - setTimeout("autoScrollToCurrentMoveIfEnabled();", Math.min(666, 0.9 * Delay)); - } else { - synchMoves(); - RefreshBoard(); - HighlightLastMove(); - autoScrollToCurrentMoveIfEnabled(); - // customFunctionOnMove here for consistency: null move starting new game - customFunctionOnMove(); - if (typeof(engineWinOnMove) == "function") { engineWinOnMove(); } - } + CurrentPly = StartPly; + if (firstStart || alwaysInitialHalfmove) { + GoToInitialHalfmove(); + setTimeout("autoScrollToCurrentMoveIfEnabled();", Math.min(666, 0.9 * Delay)); + } else { + synchMoves(); + RefreshBoard(); + HighlightLastMove(); + autoScrollToCurrentMoveIfEnabled(); + // customFunctionOnMove here for consistency: null move starting new game + customFunctionOnMove(); + if (typeof (engineWinOnMove) == "function") { + engineWinOnMove(); + } + } - if ((firstStart) && (autostartAutoplay)) { SetAutoPlay(true); } + if ((firstStart) && (autostartAutoplay)) { + SetAutoPlay(true); + } - customFunctionOnPgnGameLoad(); + customFunctionOnPgnGameLoad(); - initialVariation = 0; - firstStart = false; + initialVariation = 0; + firstStart = false; } function myAlertFEN(FenString, text) { - myAlert("error: invalid FEN in game " + (currentGame+1) + ": " + text + "\n" + FenString, true); + myAlert("error: invalid FEN in game " + (currentGame + 1) + ": " + text + "\n" + FenString, true); } function InitFEN(startingFEN) { - var ii, jj, cc, color, castlingRookCol, fullMoveNumber; + var ii, jj, cc, color, castlingRookCol, fullMoveNumber; - var FenString = typeof(startingFEN) != "string" ? FenStringStart : startingFEN.replace(/\\/g, "/").replace(/[^a-zA-Z0-9\s\/-]/g, " ").replace(/(^\s*|\s*$)/g, "").replace(/\s+/g, " "); + var FenString = typeof (startingFEN) != "string" ? FenStringStart : startingFEN.replace(/\\/g, "/").replace(/[^a-zA-Z0-9\s\/-]/g, " ").replace(/(^\s*|\s*$)/g, "").replace(/\s+/g, " "); - for (ii = 0; ii < 8; ++ii) { - for (jj = 0; jj < 8; ++jj) { - Board[ii][jj] = 0; - } - } - - StartPly = 0; - MoveCount = StartPly; - MoveColor = StartPly % 2; - - var newEnPassant = false; - var newEnPassantCol; - CastlingLong = [0, 0]; - CastlingShort = [7, 7]; - InitialHalfMoveClock = 0; - - HistVar[StartPly] = 0; - HistNull[StartPly] = 0; - - if (FenString == FenStringStart) { - for (color = 0; color < 2; color++) { - // K Q N B R p - PieceType[color] = [1, 2, 5, 5, 4, 4, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6]; - PieceCol[color] = [4, 3, 1, 6, 2, 5, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7]; - PieceMoveCounter[color] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - PieceRow[color] = color ? [7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6]: - [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]; - for (ii = 0; ii < 16; ii++) { - var col = PieceCol[color][ii]; - var row = PieceRow[color][ii]; - Board[col][row] = (1-2*color)*PieceType[color][ii]; - } - } - } else { - var kk, ll, nn, mm; - for (ii = 0; ii < 2; ii++) { - for (jj = 0; jj < 16; jj++) { - PieceType[ii][jj] = -1; - PieceCol[ii][jj] = 0; - PieceRow[ii][jj] = 0; - PieceMoveCounter[ii][jj] = 0; - } + for (ii = 0; ii < 8; ++ii) { + for (jj = 0; jj < 8; ++jj) { + Board[ii][jj] = 0; + } } - ii = 0; jj = 7; ll = 0; nn = 1; mm = 1; cc = FenString.charAt(ll++); - while (cc != " ") { - if (cc == "/") { - if (ii != 8) { - myAlertFEN(FenString, "piece placement: each row needs 8 squares"); - InitFEN(); - return; - } - ii = 0; - jj--; - } - if (ii == 8) { - myAlertFEN(FenString, "piece placement: each row needs 8 squares"); - InitFEN(); - return; - } - if (!isNaN(cc)) { - ii += parseInt(cc,10); - if ((ii < 0) || (ii > 8)) { - myAlertFEN(FenString, "piece placement: each row needs 8 squares"); - InitFEN(); - return; - } - } - if (cc === PiecesArr[0].toUpperCase()) { - if (PieceType[0][0] != -1) { - myAlertFEN(FenString, "piece placement: more than 1 white king"); - InitFEN(); - return; - } - PieceType[0][0] = 1; - PieceCol[0][0] = ii; - PieceRow[0][0] = jj; - ii++; - } else if (cc === PiecesArr[0].toLowerCase()) { - if (PieceType[1][0] != -1) { - myAlertFEN(FenString, "piece placement: more than 1 black king"); - InitFEN(); - return; - } - PieceType[1][0] = 1; - PieceCol[1][0] = ii; - PieceRow[1][0] = jj; - ii++; - } - for (kk = 1; kk < 6; kk++) { - if (cc === PiecesArr[kk].toUpperCase()) { - if (nn == 16) { - myAlertFEN(FenString, "piece placement: more than 16 white pieces"); - InitFEN(); - return; - } - PieceType[0][nn] = kk+1; - PieceCol[0][nn] = ii; - PieceRow[0][nn] = jj; - nn++; - ii++; - } else if (cc === PiecesArr[kk].toLowerCase()) { - if (mm==16) { - myAlertFEN(FenString, "piece placement: more than 16 black pieces"); - InitFEN(); - return; - } - PieceType[1][mm] = kk+1; - PieceCol[1][mm] = ii; - PieceRow[1][mm] = jj; - mm++; - ii++; - } - } - cc = ll < FenString.length ? FenString.charAt(ll++) : " "; - } - if ((ii != 8) || (jj !== 0)) { - myAlertFEN(FenString, "piece placement: string termination issue"); - InitFEN(); - return; - } - if ((PieceType[0][0] == -1) || (PieceType[1][0] == -1)) { - myAlertFEN(FenString, "missing king"); - InitFEN(); - return; - } - if (ll == FenString.length) { - FenString += " w " + assumedCastleRights() + " - 0 1"; - ll++; - } - cc = FenString.charAt(ll++); - if ((cc == "w") || (cc == "b")) { - if (cc == "b") { - StartPly += 1; - MoveColor = 1; - } - } else { - myAlertFEN(FenString, "invalid active color"); - } + StartPly = 0; + MoveCount = StartPly; + MoveColor = StartPly % 2; - // set board - for (color = 0; color < 2; ++color) { - for (ii = 0; ii < 16; ii++) { - if (PieceType[color][ii] != -1) { - col = PieceCol[color][ii]; - row = PieceRow[color][ii]; - Board[col][row] = (1-2*color)*(PieceType[color][ii]); - } - } - } - - ll++; - if (ll >= FenString.length) { - myAlertFEN(FenString, "missing castling availability"); - FenString += " " + assumedCastleRights() + " - 0 1"; - ll++; - } - CastlingLong = [-1, -1]; - CastlingShort = [-1, -1]; - cc = FenString.charAt(ll++); - while (cc!=" ") { - if (cc === PiecesArr[0].toUpperCase()) { - for (CastlingShort[0] = 7; CastlingShort[0] > PieceCol[0][0]; CastlingShort[0]--) { - if (Board[CastlingShort[0]][0] == 3) { break; } - } - if (CastlingShort[0] <= PieceCol[0][0]) { - myAlertFEN(FenString, "missing castling rook " + cc); - CastlingShort[0] = -1; - } - } else if (cc === PiecesArr[1].toUpperCase()) { - for (CastlingLong[0] = 0; CastlingLong[0] < PieceCol[0][0]; CastlingLong[0]++) { - if (Board[CastlingLong[0]][0] == 3) { break; } - } - if (CastlingLong[0] >= PieceCol[0][0]) { - myAlertFEN(FenString, "missing castling rook " + cc); - CastlingLong[0] = -1; - } - } else if (cc === PiecesArr[0].toLowerCase()) { - for (CastlingShort[1] = 7; CastlingShort[1] > PieceCol[1][0]; CastlingShort[1]--) { - if (Board[CastlingShort[1]][7] == -3) { break; } - } - if (CastlingShort[1] <= PieceCol[1][0]) { - myAlertFEN(FenString, "missing castling rook " + cc); - CastlingShort[1] = -1; - } - } else if (cc === PiecesArr[1].toLowerCase()) { - for (CastlingLong[1] = 0; CastlingLong[1] < PieceCol[1][0]; CastlingLong[1]++) { - if (Board[CastlingLong[1]][7] == -3) { break; } - } - if (CastlingLong[1] >= PieceCol[1][0]) { - myAlertFEN(FenString, "missing castling rook " + cc); - CastlingLong[1] = -1; - } - } - castlingRookCol = columnsLetters.toUpperCase().indexOf(cc); - if (castlingRookCol >= 0) { color = 0; } - else { - castlingRookCol = columnsLetters.toLowerCase().indexOf(cc); - if (castlingRookCol >= 0) { color = 1; } - } - if (castlingRookCol >= 0) { - if (Board[castlingRookCol][color*7] == (1-2*color) * 3) { - if (castlingRookCol > PieceCol[color][0]) { CastlingShort[color] = castlingRookCol; } - if (castlingRookCol < PieceCol[color][0]) { CastlingLong[color] = castlingRookCol; } - } else { - myAlertFEN(FenString, "missing castling rook " + cc); - } - } - cc = ll= FenString.length) { - myAlertFEN(FenString, "missing en passant square"); - FenString += " - 0 1"; - ll++; - } - cc = FenString.charAt(ll++); - while (cc != " ") { - if ((cc.charCodeAt(0)-97 >= 0) && (cc.charCodeAt(0)-97 <= 7)) { - newEnPassant = true; - newEnPassantCol = cc.charCodeAt(0)-97; - } - cc = ll= FenString.length) { - myAlertFEN(FenString, "missing halfmove clock"); - FenString += " 0 1"; - ll++; - } + var newEnPassant = false; + var newEnPassantCol; + CastlingLong = [0, 0]; + CastlingShort = [7, 7]; InitialHalfMoveClock = 0; - cc = FenString.charAt(ll++); - while (cc != " ") { - if (isNaN(cc)) { - myAlertFEN(FenString, "invalid halfmove clock"); - break; - } - InitialHalfMoveClock=InitialHalfMoveClock*10+parseInt(cc,10); - cc = ll= FenString.length) { - myAlertFEN(FenString, "missing fullmove number"); - FenString += " 1"; - ll++; - } - fullMoveNumber = 0; - cc = FenString.charAt(ll++); - while (cc != " ") { - if (isNaN(cc)) { - myAlertFEN(FenString, "invalid fullmove number"); - fullMoveNumber = 1; - break; - } - fullMoveNumber = fullMoveNumber*10+parseInt(cc,10); - cc = ll 8)) { + myAlertFEN(FenString, "piece placement: each row needs 8 squares"); + InitFEN(); + return; + } + } + if (cc === PiecesArr[0].toUpperCase()) { + if (PieceType[0][0] != -1) { + myAlertFEN(FenString, "piece placement: more than 1 white king"); + InitFEN(); + return; + } + PieceType[0][0] = 1; + PieceCol[0][0] = ii; + PieceRow[0][0] = jj; + ii++; + } else if (cc === PiecesArr[0].toLowerCase()) { + if (PieceType[1][0] != -1) { + myAlertFEN(FenString, "piece placement: more than 1 black king"); + InitFEN(); + return; + } + PieceType[1][0] = 1; + PieceCol[1][0] = ii; + PieceRow[1][0] = jj; + ii++; + } + for (kk = 1; kk < 6; kk++) { + if (cc === PiecesArr[kk].toUpperCase()) { + if (nn == 16) { + myAlertFEN(FenString, "piece placement: more than 16 white pieces"); + InitFEN(); + return; + } + PieceType[0][nn] = kk + 1; + PieceCol[0][nn] = ii; + PieceRow[0][nn] = jj; + nn++; + ii++; + } else if (cc === PiecesArr[kk].toLowerCase()) { + if (mm == 16) { + myAlertFEN(FenString, "piece placement: more than 16 black pieces"); + InitFEN(); + return; + } + PieceType[1][mm] = kk + 1; + PieceCol[1][mm] = ii; + PieceRow[1][mm] = jj; + mm++; + ii++; + } + } + cc = ll < FenString.length ? FenString.charAt(ll++) : " "; + } + if ((ii != 8) || (jj !== 0)) { + myAlertFEN(FenString, "piece placement: string termination issue"); + InitFEN(); + return; + } + if ((PieceType[0][0] == -1) || (PieceType[1][0] == -1)) { + myAlertFEN(FenString, "missing king"); + InitFEN(); + return; + } + if (ll == FenString.length) { + FenString += " w " + assumedCastleRights() + " - 0 1"; + ll++; + } + cc = FenString.charAt(ll++); + if ((cc == "w") || (cc == "b")) { + if (cc == "b") { + StartPly += 1; + MoveColor = 1; + } + } else { + myAlertFEN(FenString, "invalid active color"); + } + + // set board + for (color = 0; color < 2; ++color) { + for (ii = 0; ii < 16; ii++) { + if (PieceType[color][ii] != -1) { + col = PieceCol[color][ii]; + row = PieceRow[color][ii]; + Board[col][row] = (1 - 2 * color) * (PieceType[color][ii]); + } + } + } + + ll++; + if (ll >= FenString.length) { + myAlertFEN(FenString, "missing castling availability"); + FenString += " " + assumedCastleRights() + " - 0 1"; + ll++; + } + CastlingLong = [-1, -1]; + CastlingShort = [-1, -1]; + cc = FenString.charAt(ll++); + while (cc != " ") { + if (cc === PiecesArr[0].toUpperCase()) { + for (CastlingShort[0] = 7; CastlingShort[0] > PieceCol[0][0]; CastlingShort[0]--) { + if (Board[CastlingShort[0]][0] == 3) { + break; + } + } + if (CastlingShort[0] <= PieceCol[0][0]) { + myAlertFEN(FenString, "missing castling rook " + cc); + CastlingShort[0] = -1; + } + } else if (cc === PiecesArr[1].toUpperCase()) { + for (CastlingLong[0] = 0; CastlingLong[0] < PieceCol[0][0]; CastlingLong[0]++) { + if (Board[CastlingLong[0]][0] == 3) { + break; + } + } + if (CastlingLong[0] >= PieceCol[0][0]) { + myAlertFEN(FenString, "missing castling rook " + cc); + CastlingLong[0] = -1; + } + } else if (cc === PiecesArr[0].toLowerCase()) { + for (CastlingShort[1] = 7; CastlingShort[1] > PieceCol[1][0]; CastlingShort[1]--) { + if (Board[CastlingShort[1]][7] == -3) { + break; + } + } + if (CastlingShort[1] <= PieceCol[1][0]) { + myAlertFEN(FenString, "missing castling rook " + cc); + CastlingShort[1] = -1; + } + } else if (cc === PiecesArr[1].toLowerCase()) { + for (CastlingLong[1] = 0; CastlingLong[1] < PieceCol[1][0]; CastlingLong[1]++) { + if (Board[CastlingLong[1]][7] == -3) { + break; + } + } + if (CastlingLong[1] >= PieceCol[1][0]) { + myAlertFEN(FenString, "missing castling rook " + cc); + CastlingLong[1] = -1; + } + } + castlingRookCol = columnsLetters.toUpperCase().indexOf(cc); + if (castlingRookCol >= 0) { + color = 0; + } else { + castlingRookCol = columnsLetters.toLowerCase().indexOf(cc); + if (castlingRookCol >= 0) { + color = 1; + } + } + if (castlingRookCol >= 0) { + if (Board[castlingRookCol][color * 7] == (1 - 2 * color) * 3) { + if (castlingRookCol > PieceCol[color][0]) { + CastlingShort[color] = castlingRookCol; + } + if (castlingRookCol < PieceCol[color][0]) { + CastlingLong[color] = castlingRookCol; + } + } else { + myAlertFEN(FenString, "missing castling rook " + cc); + } + } + cc = ll < FenString.length ? FenString.charAt(ll++) : " "; + } + + if (ll >= FenString.length) { + myAlertFEN(FenString, "missing en passant square"); + FenString += " - 0 1"; + ll++; + } + cc = FenString.charAt(ll++); + while (cc != " ") { + if ((cc.charCodeAt(0) - 97 >= 0) && (cc.charCodeAt(0) - 97 <= 7)) { + newEnPassant = true; + newEnPassantCol = cc.charCodeAt(0) - 97; + } + cc = ll < FenString.length ? FenString.charAt(ll++) : " "; + } + if (ll >= FenString.length) { + myAlertFEN(FenString, "missing halfmove clock"); + FenString += " 0 1"; + ll++; + } + InitialHalfMoveClock = 0; + cc = FenString.charAt(ll++); + while (cc != " ") { + if (isNaN(cc)) { + myAlertFEN(FenString, "invalid halfmove clock"); + break; + } + InitialHalfMoveClock = InitialHalfMoveClock * 10 + parseInt(cc, 10); + cc = ll < FenString.length ? FenString.charAt(ll++) : " "; + } + if (ll >= FenString.length) { + myAlertFEN(FenString, "missing fullmove number"); + FenString += " 1"; + ll++; + } + + fullMoveNumber = 0; + cc = FenString.charAt(ll++); + while (cc != " ") { + if (isNaN(cc)) { + myAlertFEN(FenString, "invalid fullmove number"); + fullMoveNumber = 1; + break; + } + fullMoveNumber = fullMoveNumber * 10 + parseInt(cc, 10); + cc = ll < FenString.length ? FenString.charAt(ll++) : " "; + } + if (fullMoveNumber === 0) { + myAlertFEN(FenString, "invalid fullmove 0 set to 1"); + fullMoveNumber = 1; + } + StartPly += 2 * (fullMoveNumber - 1); + + if (IsCheck(PieceCol[MoveColor ? 0 : 1][0], PieceRow[MoveColor ? 0 : 1][0], MoveColor ? 0 : 1)) { + myAlertFEN(FenString, (MoveColor ? "Black" : "White") + " to move checking " + (MoveColor ? "white" : "black") + " king"); + } + + HistEnPassant[StartPly] = newEnPassant; + HistEnPassantCol[StartPly] = newEnPassantCol; + HistNull[StartPly] = 0; + HistVar[StartPly] = 0; + } } // castling rights assuming kings and rooks starting positions as in normal chess function assumedCastleRights() { - var ii, rights = ""; - if ((PieceRow[0][0] === 0) && (PieceCol[0][0] === 4)) { - for (ii = 0; ii < PieceType[0].length; ii++) { - if ((PieceType[0][ii] === 3) && (PieceRow[0][ii] === 0) && (PieceCol[0][ii] === 7)) { - rights += PiecesArr[0].toUpperCase(); - } else if ((PieceType[0][ii] === 3) && (PieceRow[0][ii] === 0) && (PieceCol[0][ii] === 0)) { - rights += PiecesArr[1].toUpperCase(); - } + var ii, rights = ""; + if ((PieceRow[0][0] === 0) && (PieceCol[0][0] === 4)) { + for (ii = 0; ii < PieceType[0].length; ii++) { + if ((PieceType[0][ii] === 3) && (PieceRow[0][ii] === 0) && (PieceCol[0][ii] === 7)) { + rights += PiecesArr[0].toUpperCase(); + } else if ((PieceType[0][ii] === 3) && (PieceRow[0][ii] === 0) && (PieceCol[0][ii] === 0)) { + rights += PiecesArr[1].toUpperCase(); + } + } } - } - if ((PieceRow[1][0] === 7) && (PieceCol[1][0] === 4)) { - for (ii = 0; ii < PieceType[1].length; ii++) { - if ((PieceType[1][ii] === 3) && (PieceRow[1][ii] === 7) && (PieceCol[1][ii] === 7)) { - rights += PiecesArr[0].toLowerCase(); - } else if ((PieceType[1][ii] === 3) && (PieceRow[1][ii] === 7) && (PieceCol[1][ii] === 0)) { - rights += PiecesArr[1].toLowerCase(); - } + if ((PieceRow[1][0] === 7) && (PieceCol[1][0] === 4)) { + for (ii = 0; ii < PieceType[1].length; ii++) { + if ((PieceType[1][ii] === 3) && (PieceRow[1][ii] === 7) && (PieceCol[1][ii] === 7)) { + rights += PiecesArr[0].toLowerCase(); + } else if ((PieceType[1][ii] === 3) && (PieceRow[1][ii] === 7) && (PieceCol[1][ii] === 0)) { + rights += PiecesArr[1].toLowerCase(); + } + } } - } - return rights || "-"; + return rights || "-"; } function SetImageType(extension) { - imageType = extension; + imageType = extension; } function InitImages() { - if (ImagePathOld === ImagePath) { return; } - - if ((ImagePath.length > 0) && (ImagePath[ImagePath.length-1] != '/')) { - ImagePath += '/'; - } - - ClearImg = new Image(); - ClearImg.src = ImagePath + 'clear.' + imageType; - - var ColorName = new Array ("w", "b"); - var PiecePrefix = new Array ("k", "q", "r", "b", "n", "p"); - for (var c=0; c<2; ++c) { - for (var p=1; p<7; p++) { - PieceImg[c][p] = new Image(); - PieceImg[c][p].src = ImagePath + ColorName[c] + PiecePrefix[p-1] + '.' + imageType; + if (ImagePathOld === ImagePath) { + return; } - } - ImagePathOld = ImagePath; + + if ((ImagePath.length > 0) && (ImagePath[ImagePath.length - 1] != '/')) { + ImagePath += '/'; + } + + ClearImg = new Image(); + ClearImg.src = ImagePath + 'clear.' + imageType; + + var ColorName = new Array("w", "b"); + var PiecePrefix = new Array("k", "q", "r", "b", "n", "p"); + for (var c = 0; c < 2; ++c) { + for (var p = 1; p < 7; p++) { + PieceImg[c][p] = new Image(); + PieceImg[c][p].src = ImagePath + ColorName[c] + PiecePrefix[p - 1] + '.' + imageType; + } + } + ImagePathOld = ImagePath; } function IsCheck(col, row, color) { - var ii, jj; - var sign = 2*color-1; // white or black + var ii, jj; + var sign = 2 * color - 1; // white or black - // other king giving check? - if ((Math.abs(PieceCol[1-color][0]-col) <= 1) && (Math.abs(PieceRow[1-color][0]-row) <= 1)) { return true; } - - // knight? - for (ii = -2; ii <= 2; ii += 4) { - for (jj = -1; jj <= 1; jj += 2) { - if (SquareOnBoard(col+ii, row+jj)) { - if (Board[col+ii][row+jj] == sign*5) { return true; } - } - if (SquareOnBoard(col+jj, row+ii)) { - if (Board[col+jj][row+ii] == sign*5) { return true; } - } + // other king giving check? + if ((Math.abs(PieceCol[1 - color][0] - col) <= 1) && (Math.abs(PieceRow[1 - color][0] - row) <= 1)) { + return true; } - } - // pawn? - for (ii = -1; ii <= 1; ii += 2) { - if (SquareOnBoard(col+ii, row-sign)) { - if (Board[col+ii][row-sign] == sign*6) { return true; } - } - } - - // queens, rooks, bishops? - for (ii = -1; ii <= 1; ++ii) { - for (jj = -1; jj <= 1; ++jj) { - if ((ii !== 0) || (jj !== 0)) { - var checkCol = col+ii; - var checkRow = row+jj; - var thisPiece = 0; - - while (SquareOnBoard(checkCol, checkRow) && (thisPiece === 0)) { - thisPiece = Board[checkCol][checkRow]; - if (thisPiece === 0) { - checkCol += ii; - checkRow += jj; - } else { - if (thisPiece == sign*2) { return true; } - if ((thisPiece == sign*3) && ((ii === 0) || (jj === 0))) { return true; } - if ((thisPiece == sign*4) && ((ii !== 0) && (jj !== 0))) { return true; } - } + // knight? + for (ii = -2; ii <= 2; ii += 4) { + for (jj = -1; jj <= 1; jj += 2) { + if (SquareOnBoard(col + ii, row + jj)) { + if (Board[col + ii][row + jj] == sign * 5) { + return true; + } + } + if (SquareOnBoard(col + jj, row + ii)) { + if (Board[col + jj][row + ii] == sign * 5) { + return true; + } + } } - } } - } - return false; + + // pawn? + for (ii = -1; ii <= 1; ii += 2) { + if (SquareOnBoard(col + ii, row - sign)) { + if (Board[col + ii][row - sign] == sign * 6) { + return true; + } + } + } + + // queens, rooks, bishops? + for (ii = -1; ii <= 1; ++ii) { + for (jj = -1; jj <= 1; ++jj) { + if ((ii !== 0) || (jj !== 0)) { + var checkCol = col + ii; + var checkRow = row + jj; + var thisPiece = 0; + + while (SquareOnBoard(checkCol, checkRow) && (thisPiece === 0)) { + thisPiece = Board[checkCol][checkRow]; + if (thisPiece === 0) { + checkCol += ii; + checkRow += jj; + } else { + if (thisPiece == sign * 2) { + return true; + } + if ((thisPiece == sign * 3) && ((ii === 0) || (jj === 0))) { + return true; + } + if ((thisPiece == sign * 4) && ((ii !== 0) && (jj !== 0))) { + return true; + } + } + } + } + } + } + return false; } function fixRegExp(exp) { - return exp.replace(/([\[\]\(\)\{\}\.\*\+\^\$\|\?\\])/g, "\\$1"); + return exp.replace(/([\[\]\(\)\{\}\.\*\+\^\$\|\?\\])/g, "\\$1"); } function LoadGameHeaders() { - var ii; - var parse; + var ii; + var parse; - gameEvent.length = gameSite.length = gameRound.length = gameDate.length = 0; - gameWhite.length = gameBlack.length = gameResult.length = 0; - gameSetUp.length = gameFEN.length = 0; - gameInitialWhiteClock.length = gameInitialBlackClock.length = 0; - gameVariant.length = 0; + gameEvent.length = gameSite.length = gameRound.length = gameDate.length = 0; + gameWhite.length = gameBlack.length = gameResult.length = 0; + gameSetUp.length = gameFEN.length = 0; + gameInitialWhiteClock.length = gameInitialBlackClock.length = 0; + gameVariant.length = 0; - pgnHeaderTagRegExpGlobal.lastIndex = 0; // resets global regular expression - for (ii = 0; ii < numberOfGames; ++ii) { - var ss = pgnHeader[ii]; - gameEvent[ii] = gameSite[ii] = gameRound[ii] = gameDate[ii] = ""; - gameWhite[ii] = gameBlack[ii] = gameResult[ii] = ""; - gameInitialWhiteClock[ii] = gameInitialBlackClock[ii] = ""; - gameVariant[ii] = ""; - while (parse = pgnHeaderTagRegExpGlobal.exec(ss)) { - switch (parse[1]) { - case 'Event': gameEvent[ii] = parse[2]; break; - case 'Site': gameSite[ii] = parse[2]; break; - case 'Round': gameRound[ii] = parse[2]; break; - case 'Date': gameDate[ii] = parse[2]; break; - case 'White': gameWhite[ii] = parse[2]; break; - case 'Black': gameBlack[ii] = parse[2]; break; - case 'Result': gameResult[ii] = parse[2]; break; - case 'SetUp': gameSetUp[ii] = parse[2]; break; - case 'FEN': gameFEN[ii] = parse[2]; break; - case 'WhiteClock': gameInitialWhiteClock[ii] = parse[2]; break; - case 'BlackClock': gameInitialBlackClock[ii] = parse[2]; break; - case 'Variant': gameVariant[ii] = parse[2]; break; - default: break; - } - } - } - if ((LiveBroadcastDemo) && (numberOfGames > 0)) { + pgnHeaderTagRegExpGlobal.lastIndex = 0; // resets global regular expression for (ii = 0; ii < numberOfGames; ++ii) { - if ((gameDemoLength[ii] === undefined) || (gameDemoLength[ii] === 0)) { - InitFEN(gameFEN[ii]); - ParsePGNGameString(pgnGame[ii]); - gameDemoLength[ii] = PlyNumber; - } - if (gameDemoMaxPly[ii] === undefined) { gameDemoMaxPly[ii] = 0; } - if ((gameDemoMaxPly[ii] <= gameDemoLength[ii]) && (gameDemoLength[ii] > 0)) { gameResult[ii] = '*'; } + var ss = pgnHeader[ii]; + gameEvent[ii] = gameSite[ii] = gameRound[ii] = gameDate[ii] = ""; + gameWhite[ii] = gameBlack[ii] = gameResult[ii] = ""; + gameInitialWhiteClock[ii] = gameInitialBlackClock[ii] = ""; + gameVariant[ii] = ""; + while (parse = pgnHeaderTagRegExpGlobal.exec(ss)) { + switch (parse[1]) { + case 'Event': + gameEvent[ii] = parse[2]; + break; + case 'Site': + gameSite[ii] = parse[2]; + break; + case 'Round': + gameRound[ii] = parse[2]; + break; + case 'Date': + gameDate[ii] = parse[2]; + break; + case 'White': + gameWhite[ii] = parse[2]; + break; + case 'Black': + gameBlack[ii] = parse[2]; + break; + case 'Result': + gameResult[ii] = parse[2]; + break; + case 'SetUp': + gameSetUp[ii] = parse[2]; + break; + case 'FEN': + gameFEN[ii] = parse[2]; + break; + case 'WhiteClock': + gameInitialWhiteClock[ii] = parse[2]; + break; + case 'BlackClock': + gameInitialBlackClock[ii] = parse[2]; + break; + case 'Variant': + gameVariant[ii] = parse[2]; + break; + default: + break; + } + } } - } - return; + if ((LiveBroadcastDemo) && (numberOfGames > 0)) { + for (ii = 0; ii < numberOfGames; ++ii) { + if ((gameDemoLength[ii] === undefined) || (gameDemoLength[ii] === 0)) { + InitFEN(gameFEN[ii]); + ParsePGNGameString(pgnGame[ii]); + gameDemoLength[ii] = PlyNumber; + } + if (gameDemoMaxPly[ii] === undefined) { + gameDemoMaxPly[ii] = 0; + } + if ((gameDemoMaxPly[ii] <= gameDemoLength[ii]) && (gameDemoLength[ii] > 0)) { + gameResult[ii] = '*'; + } + } + } + return; } function MoveBackward(diff, scanOnly) { - // CurrentPly counts from 1, starting position 0 - var goFromPly = CurrentPly - 1; - var goToPly = goFromPly - diff; - if (goToPly < StartPly) { goToPly = StartPly-1; } + // CurrentPly counts from 1, starting position 0 + var goFromPly = CurrentPly - 1; + var goToPly = goFromPly - diff; + if (goToPly < StartPly) { + goToPly = StartPly - 1; + } - // reconstruct old position - for (var thisPly = goFromPly; thisPly > goToPly; --thisPly) { - CurrentPly--; - MoveColor = 1-MoveColor; - CurrentVar = HistVar[thisPly]; - UndoMove(thisPly); - } + // reconstruct old position + for (var thisPly = goFromPly; thisPly > goToPly; --thisPly) { + CurrentPly--; + MoveColor = 1 - MoveColor; + CurrentVar = HistVar[thisPly]; + UndoMove(thisPly); + } - if (scanOnly) { return; } + if (scanOnly) { + return; + } - synchMoves(); + synchMoves(); - // old position reconstructed: refresh board - RefreshBoard(); - HighlightLastMove(); + // old position reconstructed: refresh board + RefreshBoard(); + HighlightLastMove(); - autoScrollToCurrentMoveIfEnabled(); + autoScrollToCurrentMoveIfEnabled(); - // autoplay: restart timeout - if (AutoPlayInterval) { clearTimeout(AutoPlayInterval); AutoPlayInterval = null; } - if (isAutoPlayOn) { - if (goToPly >= StartPlyVar[CurrentVar]) { AutoPlayInterval=setTimeout("MoveBackward(1)", Delay); } - else { SetAutoPlay(false); } - } + // autoplay: restart timeout + if (AutoPlayInterval) { + clearTimeout(AutoPlayInterval); + AutoPlayInterval = null; + } + if (isAutoPlayOn) { + if (goToPly >= StartPlyVar[CurrentVar]) { + AutoPlayInterval = setTimeout("MoveBackward(1)", Delay); + } else { + SetAutoPlay(false); + } + } - customFunctionOnMove(); - if (typeof(engineWinOnMove) == "function") { engineWinOnMove(); } + customFunctionOnMove(); + if (typeof (engineWinOnMove) == "function") { + engineWinOnMove(); + } } function MoveForward(diff, targetVar, scanOnly) { - var nextVar, nextVarStartPly, move, text; - var oldVar = -1; + var nextVar, nextVarStartPly, move, text; + var oldVar = -1; - if (typeof(targetVar) == "undefined") { targetVar = CurrentVar; } + if (typeof (targetVar) == "undefined") { + targetVar = CurrentVar; + } - // CurrentPly counts from 1, starting position 0 - var goToPly = CurrentPly + parseInt(diff,10); + // CurrentPly counts from 1, starting position 0 + var goToPly = CurrentPly + parseInt(diff, 10); - if (goToPly > StartPlyVar[targetVar] + PlyNumberVar[targetVar]) { - goToPly = StartPlyVar[targetVar] + PlyNumberVar[targetVar]; - } + if (goToPly > StartPlyVar[targetVar] + PlyNumberVar[targetVar]) { + goToPly = StartPlyVar[targetVar] + PlyNumberVar[targetVar]; + } - // reach to selected move checking legality - for (var thisPly = CurrentPly; thisPly < goToPly; ++thisPly) { + // reach to selected move checking legality + for (var thisPly = CurrentPly; thisPly < goToPly; ++thisPly) { - if (targetVar !== CurrentVar) { - for (var ii = 0; ii < PredecessorsVars[targetVar].length; ii++) { - if (PredecessorsVars[targetVar][ii] === CurrentVar) { break; } - } - if (ii === PredecessorsVars[targetVar].length) { - myAlert("error: unknown path to variation " + targetVar + " from " + CurrentVar + " in game " + (currentGame+1), true); - return; - } else { - nextVarStartPly = StartPlyVar[PredecessorsVars[targetVar][ii + 1]]; - for (ii = ii+1; ii < PredecessorsVars[targetVar].length - 1; ii++) { - if (StartPlyVar[PredecessorsVars[targetVar][ii+1]] !== StartPlyVar[PredecessorsVars[targetVar][ii]] ) { break; } + if (targetVar !== CurrentVar) { + for (var ii = 0; ii < PredecessorsVars[targetVar].length; ii++) { + if (PredecessorsVars[targetVar][ii] === CurrentVar) { + break; + } + } + if (ii === PredecessorsVars[targetVar].length) { + myAlert("error: unknown path to variation " + targetVar + " from " + CurrentVar + " in game " + (currentGame + 1), true); + return; + } else { + nextVarStartPly = StartPlyVar[PredecessorsVars[targetVar][ii + 1]]; + for (ii = ii + 1; ii < PredecessorsVars[targetVar].length - 1; ii++) { + if (StartPlyVar[PredecessorsVars[targetVar][ii + 1]] !== StartPlyVar[PredecessorsVars[targetVar][ii]]) { + break; + } + } + nextVar = PredecessorsVars[targetVar][ii]; + } + } else { + nextVar = nextVarStartPly = -1; } - nextVar = PredecessorsVars[targetVar][ii]; - } - } else { nextVar = nextVarStartPly = -1; } - if (thisPly === nextVarStartPly) { - oldVar = CurrentVar; - CurrentVar = nextVar; + if (thisPly === nextVarStartPly) { + oldVar = CurrentVar; + CurrentVar = nextVar; + } + + if (typeof (move = MovesVar[CurrentVar][thisPly]) == "undefined") { + break; + } + + if (ParseLastMoveError = !ParseMove(move, thisPly)) { + text = (Math.floor(thisPly / 2) + 1) + ((thisPly % 2) === 0 ? '. ' : '... '); + myAlert('error: invalid ply ' + text + move + ' in game ' + (currentGame + 1) + ' variation ' + CurrentVar, true); + if (thisPly === nextVarStartPly) { + CurrentVar = oldVar; + } + break; + } + MoveColor = 1 - MoveColor; + } - if (typeof(move = MovesVar[CurrentVar][thisPly]) == "undefined") { break; } + // new position: update ply count, then refresh board + CurrentPly = thisPly; - if (ParseLastMoveError = !ParseMove(move, thisPly)) { - text = (Math.floor(thisPly / 2) + 1) + ((thisPly % 2) === 0 ? '. ' : '... '); - myAlert('error: invalid ply ' + text + move + ' in game ' + (currentGame+1) + ' variation ' + CurrentVar, true); - if (thisPly === nextVarStartPly) { CurrentVar = oldVar; } - break; + if (scanOnly) { + return; } - MoveColor = 1-MoveColor; - } + synchMoves(); - // new position: update ply count, then refresh board - CurrentPly = thisPly; + RefreshBoard(); + HighlightLastMove(); - if (scanOnly) { return; } + autoScrollToCurrentMoveIfEnabled(); - synchMoves(); - - RefreshBoard(); - HighlightLastMove(); - - autoScrollToCurrentMoveIfEnabled(); - - // autoplay: restart timeout - if (AutoPlayInterval) { clearTimeout(AutoPlayInterval); AutoPlayInterval = null; } - if (ParseLastMoveError) { SetAutoPlay(false); } - else if (thisPly == goToPly) { - if (isAutoPlayOn) { - if (goToPly < StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]) { - AutoPlayInterval=setTimeout("MoveForward(1)", Delay); - } else { - if (autoplayNextGame && (CurrentVar === 0)) { AutoPlayInterval=setTimeout("AutoplayNextGame()", Delay); } - else { SetAutoPlay(false); } - } + // autoplay: restart timeout + if (AutoPlayInterval) { + clearTimeout(AutoPlayInterval); + AutoPlayInterval = null; + } + if (ParseLastMoveError) { + SetAutoPlay(false); + } else if (thisPly == goToPly) { + if (isAutoPlayOn) { + if (goToPly < StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]) { + AutoPlayInterval = setTimeout("MoveForward(1)", Delay); + } else { + if (autoplayNextGame && (CurrentVar === 0)) { + AutoPlayInterval = setTimeout("AutoplayNextGame()", Delay); + } else { + SetAutoPlay(false); + } + } + } } - } - customFunctionOnMove(); - if (typeof(engineWinOnMove) == "function") { engineWinOnMove(); } + customFunctionOnMove(); + if (typeof (engineWinOnMove) == "function") { + engineWinOnMove(); + } } var lastSynchCurrentVar = -1; + function synchMoves() { - var start, end; - if (CurrentVar === lastSynchCurrentVar) { return; } - Moves = new Array(); - MoveComments = new Array(); - for (var ii = 0; ii < PredecessorsVars[CurrentVar].length; ii++) { - start = StartPlyVar[PredecessorsVars[CurrentVar][ii]]; - if (ii < PredecessorsVars[CurrentVar].length - 1) { - end = StartPlyVar[PredecessorsVars[CurrentVar][ii+1]]; - } else { - end = StartPlyVar[PredecessorsVars[CurrentVar][ii]] + PlyNumberVar[PredecessorsVars[CurrentVar][ii]]; + var start, end; + if (CurrentVar === lastSynchCurrentVar) { + return; } - for (var jj = start; jj < end; jj++) { - Moves[jj] = MovesVar[PredecessorsVars[CurrentVar][ii]][jj]; - MoveComments[jj] = MoveCommentsVar[PredecessorsVars[CurrentVar][ii]][jj] || ""; + Moves = new Array(); + MoveComments = new Array(); + for (var ii = 0; ii < PredecessorsVars[CurrentVar].length; ii++) { + start = StartPlyVar[PredecessorsVars[CurrentVar][ii]]; + if (ii < PredecessorsVars[CurrentVar].length - 1) { + end = StartPlyVar[PredecessorsVars[CurrentVar][ii + 1]]; + } else { + end = StartPlyVar[PredecessorsVars[CurrentVar][ii]] + PlyNumberVar[PredecessorsVars[CurrentVar][ii]]; + } + for (var jj = start; jj < end; jj++) { + Moves[jj] = MovesVar[PredecessorsVars[CurrentVar][ii]][jj]; + MoveComments[jj] = MoveCommentsVar[PredecessorsVars[CurrentVar][ii]][jj] || ""; + } } - } - MoveComments[jj] = MoveCommentsVar[PredecessorsVars[CurrentVar][ii-1]][jj] || ""; - PlyNumber = StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar] - StartPly; - lastSynchCurrentVar = CurrentVar; + MoveComments[jj] = MoveCommentsVar[PredecessorsVars[CurrentVar][ii - 1]][jj] || ""; + PlyNumber = StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar] - StartPly; + lastSynchCurrentVar = CurrentVar; } function AutoplayNextGame() { - if (fatalErrorNumSinceReset === 0) { - if (numberOfGames > 0) { - Init((currentGame + 1) % numberOfGames); - if ((numberOfGames > 1) || (PlyNumber > 0)) { - SetAutoPlay(true); - return; - } + if (fatalErrorNumSinceReset === 0) { + if (numberOfGames > 0) { + Init((currentGame + 1) % numberOfGames); + if ((numberOfGames > 1) || (PlyNumber > 0)) { + SetAutoPlay(true); + return; + } + } } - } - SetAutoPlay(false); + SetAutoPlay(false); } function MoveToNextComment(varOnly) { - for (var ii=CurrentPly+1; ii<=StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]; ii++) { - if (MoveComments[ii].match(pgn4webVariationRegExp) || (!varOnly && strippedMoveComment(ii))) { GoToMove(ii); break; } - } + for (var ii = CurrentPly + 1; ii <= StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]; ii++) { + if (MoveComments[ii].match(pgn4webVariationRegExp) || (!varOnly && strippedMoveComment(ii))) { + GoToMove(ii); + break; + } + } } function MoveToPrevComment(varOnly) { - for (var ii=(CurrentPly-1); ii>=StartPly; ii--) { - if ((ii > 0 || CurrentVar > 0) && ii === StartPlyVar[HistVar[ii+1]]) { GoToMove(ii+1, HistVar[ii]); break; } - if (MoveComments[ii].match(pgn4webVariationRegExp) || (!varOnly && strippedMoveComment(ii))) { GoToMove(ii); break; } - } + for (var ii = (CurrentPly - 1); ii >= StartPly; ii--) { + if ((ii > 0 || CurrentVar > 0) && ii === StartPlyVar[HistVar[ii + 1]]) { + GoToMove(ii + 1, HistVar[ii]); + break; + } + if (MoveComments[ii].match(pgn4webVariationRegExp) || (!varOnly && strippedMoveComment(ii))) { + GoToMove(ii); + break; + } + } } function OpenGame(gameId) { - ParsePGNGameString(pgnGame[gameId]); - currentGame = gameId; - ParseLastMoveError = false; + ParsePGNGameString(pgnGame[gameId]); + currentGame = gameId; + ParseLastMoveError = false; - if (LiveBroadcastDemo) { - if (gameDemoMaxPly[gameId] <= PlyNumber) { PlyNumber = PlyNumberVar[0] = gameDemoMaxPly[gameId]; } - } + if (LiveBroadcastDemo) { + if (gameDemoMaxPly[gameId] <= PlyNumber) { + PlyNumber = PlyNumberVar[0] = gameDemoMaxPly[gameId]; + } + } - PrintHTML(false); + PrintHTML(false); } var CurrentVar = -1; @@ -2741,259 +3595,311 @@ var CurrentVarStack; var PlyNumberStack; var PredecessorsVars; -function initVar () { - MovesVar = new Array(); - MoveCommentsVar = new Array(); - GameHasComments = false; - GameHasVariations = false; - StartPlyVar = new Array(); - PlyNumberVar = new Array(); - CurrentVar = -1; - lastVarWithNoMoves = [false]; - numberOfVars = 0; - CurrentVarStack = new Array(); - PlyNumber = 1; - PlyNumberStack = new Array(); - PredecessorsVars = new Array(); - startVar(false); +function initVar() { + MovesVar = new Array(); + MoveCommentsVar = new Array(); + GameHasComments = false; + GameHasVariations = false; + StartPlyVar = new Array(); + PlyNumberVar = new Array(); + CurrentVar = -1; + lastVarWithNoMoves = [false]; + numberOfVars = 0; + CurrentVarStack = new Array(); + PlyNumber = 1; + PlyNumberStack = new Array(); + PredecessorsVars = new Array(); + startVar(false); } function startVar(isContinuation) { - if (CurrentVar >= 0) { - CurrentVarStack.push(CurrentVar); - PlyNumberStack.push(PlyNumber); - } - CurrentVar = numberOfVars++; - PredecessorsVars[CurrentVar] = CurrentVarStack.slice(0); - PredecessorsVars[CurrentVar].push(CurrentVar); - MovesVar[CurrentVar] = new Array(); - MoveCommentsVar[CurrentVar] = new Array(); - if (!isContinuation) { - if (lastVarWithNoMoves[lastVarWithNoMoves.length - 1]) { - myAlert("warning: malformed PGN data in game " + (currentGame+1) + ": variation " + CurrentVar + " starting before parent", true); - } else { - PlyNumber -= 1; + if (CurrentVar >= 0) { + CurrentVarStack.push(CurrentVar); + PlyNumberStack.push(PlyNumber); } - } - lastVarWithNoMoves.push(true); - MoveCommentsVar[CurrentVar][StartPly + PlyNumber] = ""; - StartPlyVar[CurrentVar] = StartPly + PlyNumber; + CurrentVar = numberOfVars++; + PredecessorsVars[CurrentVar] = CurrentVarStack.slice(0); + PredecessorsVars[CurrentVar].push(CurrentVar); + MovesVar[CurrentVar] = new Array(); + MoveCommentsVar[CurrentVar] = new Array(); + if (!isContinuation) { + if (lastVarWithNoMoves[lastVarWithNoMoves.length - 1]) { + myAlert("warning: malformed PGN data in game " + (currentGame + 1) + ": variation " + CurrentVar + " starting before parent", true); + } else { + PlyNumber -= 1; + } + } + lastVarWithNoMoves.push(true); + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] = ""; + StartPlyVar[CurrentVar] = StartPly + PlyNumber; } function closeVar() { - if (StartPly + PlyNumber === StartPlyVar[CurrentVar]) { - myAlert("warning: empty variation " + CurrentVar + " in game " + (currentGame+1), false); - } else { - GameHasVariations = true; - } - lastVarWithNoMoves.pop(); - PlyNumberVar[CurrentVar] = StartPly + PlyNumber - StartPlyVar[CurrentVar]; - for (var ii=StartPlyVar[CurrentVar]; ii<=StartPlyVar[CurrentVar]+PlyNumberVar[CurrentVar]; ii++) { - if (MoveCommentsVar[CurrentVar][ii]) { - MoveCommentsVar[CurrentVar][ii] = MoveCommentsVar[CurrentVar][ii].replace(/\s+/g, ' '); - MoveCommentsVar[CurrentVar][ii] = translateNAGs(MoveCommentsVar[CurrentVar][ii]); - MoveCommentsVar[CurrentVar][ii] = MoveCommentsVar[CurrentVar][ii].replace(/\s+$/g, ''); + if (StartPly + PlyNumber === StartPlyVar[CurrentVar]) { + myAlert("warning: empty variation " + CurrentVar + " in game " + (currentGame + 1), false); } else { - MoveCommentsVar[CurrentVar][ii] = ''; + GameHasVariations = true; + } + lastVarWithNoMoves.pop(); + PlyNumberVar[CurrentVar] = StartPly + PlyNumber - StartPlyVar[CurrentVar]; + for (var ii = StartPlyVar[CurrentVar]; ii <= StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]; ii++) { + if (MoveCommentsVar[CurrentVar][ii]) { + MoveCommentsVar[CurrentVar][ii] = MoveCommentsVar[CurrentVar][ii].replace(/\s+/g, ' '); + MoveCommentsVar[CurrentVar][ii] = translateNAGs(MoveCommentsVar[CurrentVar][ii]); + MoveCommentsVar[CurrentVar][ii] = MoveCommentsVar[CurrentVar][ii].replace(/\s+$/g, ''); + } else { + MoveCommentsVar[CurrentVar][ii] = ''; + } + } + if (CurrentVarStack.length) { + CurrentVar = CurrentVarStack.pop(); + PlyNumber = PlyNumberStack.pop(); + } else { + myAlert("error: closeVar error" + " in game " + (currentGame + 1), true); } - } - if (CurrentVarStack.length) { - CurrentVar = CurrentVarStack.pop(); - PlyNumber = PlyNumberStack.pop(); - } else { - myAlert("error: closeVar error" + " in game " + (currentGame+1), true); - } } function childrenVars(thisPly, thisVar) { - if (typeof(thisVar) == "undefined") { thisVar = CurrentVar; } - if (typeof(thisPly) == "undefined") { thisPly = CurrentPly; } - var children = new Array(); - for (var ii = thisVar; ii < numberOfVars; ii++) { - if ((ii === thisVar && StartPlyVar[ii] + PlyNumberVar[ii] > thisPly) || (realParentVar(ii) === thisVar && StartPlyVar[ii] === thisPly && PlyNumberVar[ii] > 0)) { - children.push(ii); + if (typeof (thisVar) == "undefined") { + thisVar = CurrentVar; } - } - return children; + if (typeof (thisPly) == "undefined") { + thisPly = CurrentPly; + } + var children = new Array(); + for (var ii = thisVar; ii < numberOfVars; ii++) { + if ((ii === thisVar && StartPlyVar[ii] + PlyNumberVar[ii] > thisPly) || (realParentVar(ii) === thisVar && StartPlyVar[ii] === thisPly && PlyNumberVar[ii] > 0)) { + children.push(ii); + } + } + return children; } function realParentVar(childVar) { - for (var ii = PredecessorsVars[childVar].length - 1; ii > 0; ii--) { - if (StartPlyVar[PredecessorsVars[childVar][ii]] !== StartPlyVar[PredecessorsVars[childVar][ii-1]]) { - return PredecessorsVars[childVar][ii-1]; + for (var ii = PredecessorsVars[childVar].length - 1; ii > 0; ii--) { + if (StartPlyVar[PredecessorsVars[childVar][ii]] !== StartPlyVar[PredecessorsVars[childVar][ii - 1]]) { + return PredecessorsVars[childVar][ii - 1]; + } } - } - return PredecessorsVars[childVar][ii]; + return PredecessorsVars[childVar][ii]; } function goToNextVariationSibling() { - if (CurrentPly === StartPly) { return false; } - var siblings = childrenVars(CurrentPly - 1, HistVar[CurrentPly - 1]); - if (siblings.length < 2) { return false; } - for (var ii = 0; ii < siblings.length; ii++) { - if (siblings[ii] === CurrentVar) { break; } - } - if (siblings[ii] !== CurrentVar) { return false; } - GoToMove(CurrentPly, siblings[(ii + 1) % siblings.length]); - return true; + if (CurrentPly === StartPly) { + return false; + } + var siblings = childrenVars(CurrentPly - 1, HistVar[CurrentPly - 1]); + if (siblings.length < 2) { + return false; + } + for (var ii = 0; ii < siblings.length; ii++) { + if (siblings[ii] === CurrentVar) { + break; + } + } + if (siblings[ii] !== CurrentVar) { + return false; + } + GoToMove(CurrentPly, siblings[(ii + 1) % siblings.length]); + return true; } function goToFirstChild() { - var children = childrenVars(CurrentPly, CurrentVar); - if (children.length < 1) { return false; } - if (children[0] === CurrentVar) { - if (children.length < 2) { return false; } - GoToMove(CurrentPly + 1, children[1]); - } else { - GoToMove(CurrentPly + 1, children[0]); - } - return true; + var children = childrenVars(CurrentPly, CurrentVar); + if (children.length < 1) { + return false; + } + if (children[0] === CurrentVar) { + if (children.length < 2) { + return false; + } + GoToMove(CurrentPly + 1, children[1]); + } else { + GoToMove(CurrentPly + 1, children[0]); + } + return true; } function ParsePGNGameString(gameString) { - var ii, start, end, move, moveCount, needle, commentStart, commentEnd, isContinuation; + var ii, start, end, move, moveCount, needle, commentStart, commentEnd, isContinuation; - var ssRep, ss = gameString, ssComm; - ss = ss.replace(pgn4webVariationRegExpGlobal, "[%_pgn4web_variation_ $1]"); - // empty variations to comments - while ((ssRep = ss.replace(/\((([\?!+#\s]|\$\d+|{[^}]*})*)\)/g, ' $1 ')) !== ss) { ss = ssRep; } - ss = ss.replace(/^\s/, ''); - ss = ss.replace(/\s$/, ''); - - initVar (); - - PlyNumber = 0; - - for (start=0; start= 0) { - commentEnd++; - if (commentEnd >= ss.length) { break; } - } - if (MoveCommentsVar[CurrentVar][StartPly+PlyNumber]) { MoveCommentsVar[CurrentVar][StartPly+PlyNumber] += ' '; } - MoveCommentsVar[CurrentVar][StartPly+PlyNumber] += translateNAGs(ss.substring(commentStart, commentEnd).replace(/(^\s*|\s*$)/, '')); - start = commentEnd - 1; - break; - - case '!': - case '?': - commentStart = start; - commentEnd = commentStart + 1; - while ('!?'.indexOf(ss.charAt(commentEnd)) >= 0) { - commentEnd++; - if (commentEnd >= ss.length) { break; } - } - if (MoveCommentsVar[CurrentVar][StartPly+PlyNumber]) { MoveCommentsVar[CurrentVar][StartPly+PlyNumber] += ' '; } - MoveCommentsVar[CurrentVar][StartPly+PlyNumber] += ss.substring(commentStart, commentEnd); - start = commentEnd - 1; - break; - - case '{': - commentStart = start+1; - commentEnd = ss.indexOf('}',start+1); - if (commentEnd < 0) { - myAlert('error: missing end comment } in game ' + (currentGame+1), true); - commentEnd = ss.length; - } - if (MoveCommentsVar[CurrentVar][StartPly+PlyNumber]) { MoveCommentsVar[CurrentVar][StartPly+PlyNumber] += ' '; } - ssComm = translateNAGs(ss.substring(commentStart, commentEnd).replace(/(^\s*|\s*$)/, '')); - MoveCommentsVar[CurrentVar][StartPly+PlyNumber] += ssComm; - GameHasComments = GameHasComments || ssComm.replace(/\[%[^\]]*\]\s*/g,'').replace(basicNAGs, '').replace(/^\s+$/,'') !== ''; - start = commentEnd; - break; - - case '%': - // % must be first char of the line - if ((start > 0) && (ss.charAt(start-1) != '\n')) { break; } - commentStart = start+1; - commentEnd = ss.indexOf('\n',start+1); - if (commentEnd < 0) { commentEnd = ss.length; } - start = commentEnd; - break; - - case ';': - commentStart = start+1; - commentEnd = ss.indexOf('\n',start+1); - if (commentEnd < 0) { commentEnd = ss.length; } - if (MoveCommentsVar[CurrentVar][StartPly+PlyNumber]) { MoveCommentsVar[CurrentVar][StartPly+PlyNumber] += ' '; } - ssComm = translateNAGs(ss.substring(commentStart, commentEnd).replace(/(^\s*|\s*$)/, '')); - MoveCommentsVar[CurrentVar][StartPly+PlyNumber] += ssComm; - GameHasComments = GameHasComments || ssComm.replace(/\[%[^\]]*\]\s*/g,'').replace(basicNAGs, '').replace(/^\s+$/,'') !== ''; - start = commentEnd; - break; - - case '(': - if (isContinuation = (ss.charAt(start+1) == '*')) { start += 1; } - MoveCommentsVar[CurrentVar][StartPly+PlyNumber] += ' [%pgn4web_variation ' + numberOfVars + '] '; - startVar(isContinuation); - break; - - case ')': - closeVar(); - break; - - default: - - needle = new Array('1-0', '0-1', '1/2-1/2', '*'); - for (ii=0; ii 0) { closeVar(); } - } + initVar(); - StartPlyVar[0] = StartPly; - PlyNumberVar[0] = PlyNumber; + PlyNumber = 0; - GameHasComments = GameHasComments || GameHasVariations; + for (start = 0; start < ss.length; start++) { - lastSynchCurrentVar = -1; + switch (ss.charAt(start)) { + + case ' ': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + break; + + case '$': + commentStart = start; + commentEnd = commentStart + 1; + while ('0123456789'.indexOf(ss.charAt(commentEnd)) >= 0) { + commentEnd++; + if (commentEnd >= ss.length) { + break; + } + } + if (MoveCommentsVar[CurrentVar][StartPly + PlyNumber]) { + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] += ' '; + } + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] += translateNAGs(ss.substring(commentStart, commentEnd).replace(/(^\s*|\s*$)/, '')); + start = commentEnd - 1; + break; + + case '!': + case '?': + commentStart = start; + commentEnd = commentStart + 1; + while ('!?'.indexOf(ss.charAt(commentEnd)) >= 0) { + commentEnd++; + if (commentEnd >= ss.length) { + break; + } + } + if (MoveCommentsVar[CurrentVar][StartPly + PlyNumber]) { + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] += ' '; + } + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] += ss.substring(commentStart, commentEnd); + start = commentEnd - 1; + break; + + case '{': + commentStart = start + 1; + commentEnd = ss.indexOf('}', start + 1); + if (commentEnd < 0) { + myAlert('error: missing end comment } in game ' + (currentGame + 1), true); + commentEnd = ss.length; + } + if (MoveCommentsVar[CurrentVar][StartPly + PlyNumber]) { + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] += ' '; + } + ssComm = translateNAGs(ss.substring(commentStart, commentEnd).replace(/(^\s*|\s*$)/, '')); + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] += ssComm; + GameHasComments = GameHasComments || ssComm.replace(/\[%[^\]]*\]\s*/g, '').replace(basicNAGs, '').replace(/^\s+$/, '') !== ''; + start = commentEnd; + break; + + case '%': + // % must be first char of the line + if ((start > 0) && (ss.charAt(start - 1) != '\n')) { + break; + } + commentStart = start + 1; + commentEnd = ss.indexOf('\n', start + 1); + if (commentEnd < 0) { + commentEnd = ss.length; + } + start = commentEnd; + break; + + case ';': + commentStart = start + 1; + commentEnd = ss.indexOf('\n', start + 1); + if (commentEnd < 0) { + commentEnd = ss.length; + } + if (MoveCommentsVar[CurrentVar][StartPly + PlyNumber]) { + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] += ' '; + } + ssComm = translateNAGs(ss.substring(commentStart, commentEnd).replace(/(^\s*|\s*$)/, '')); + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] += ssComm; + GameHasComments = GameHasComments || ssComm.replace(/\[%[^\]]*\]\s*/g, '').replace(basicNAGs, '').replace(/^\s+$/, '') !== ''; + start = commentEnd; + break; + + case '(': + if (isContinuation = (ss.charAt(start + 1) == '*')) { + start += 1; + } + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] += ' [%pgn4web_variation ' + numberOfVars + '] '; + startVar(isContinuation); + break; + + case ')': + closeVar(); + break; + + default: + + needle = new Array('1-0', '0-1', '1/2-1/2', '*'); + for (ii = 0; ii < needle.length; ii++) { + if (ss.indexOf(needle[ii], start) == start) { + if (CurrentVar === 0) { + end = ss.length; + } else { + end = start + needle[ii].length; + if (MoveCommentsVar[CurrentVar][StartPly + PlyNumber]) { + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] += ' '; + } + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] += needle[ii]; + } + start = end; + break; + } + } + if (start == ss.length) { + break; + } + + moveCount = Math.floor((StartPly + PlyNumber) / 2) + 1; + needle = moveCount.toString(); + if (ss.indexOf(needle, start) == start) { + start += needle.length; + while (' .\n\r'.indexOf(ss.charAt(start)) != -1) { + start++; + } + } + + if ((end = start + ss.substr(start).search(/[\s${;!?()]/)) < start) { + end = ss.length; + } + move = ss.substring(start, end); + MovesVar[CurrentVar][StartPly + PlyNumber] = CleanMove(move); + lastVarWithNoMoves[lastVarWithNoMoves.length - 1] = false; + if (ss.charAt(end) == ' ') { + start = end; + } else { + start = end - 1; + } + if (!MovesVar[CurrentVar][StartPly + PlyNumber].match(/^[\s+#]*$/)) { // to cope with malsformed PGN data + PlyNumber++; + MoveCommentsVar[CurrentVar][StartPly + PlyNumber] = ''; + } + break; + } + } + + if (CurrentVar !== 0) { + myAlert("error: ParsePGNGameString ends with CurrentVar " + CurrentVar + " in game " + (currentGame + 1), true); + while (CurrentVar > 0) { + closeVar(); + } + } + + StartPlyVar[0] = StartPly; + PlyNumberVar[0] = PlyNumber; + + GameHasComments = GameHasComments || GameHasVariations; + + lastSynchCurrentVar = -1; } var NAGstyle = 'default'; @@ -3076,575 +3982,742 @@ NAG[134] = 'White has decisive counterplay'; // NAG[135] = '<=>'; NAG[136] = 'White has moderate time control pressure'; // NAG[137] = '(+)'; NAG[138] = 'White has severe time control pressure'; // NAG[139] = '(+)'; -for (i=14; i<139; i+=2) { NAG[i+1] = NAG[i].replace("White", "Black"); } +for (i = 14; i < 139; i += 2) { + NAG[i + 1] = NAG[i].replace("White", "Black"); +} function translateNAGs(comment) { - var matches = comment.match(/\$+[0-9]+/g); - if (matches) { - for (var ii = 0; ii < matches.length; ii++) { - var nag = matches[ii].substr(1); - if (NAG[nag] !== undefined) { - comment = comment.replace(new RegExp("\\$+" + nag + "(?!\\d)"), NAG[nag]); - } + var matches = comment.match(/\$+[0-9]+/g); + if (matches) { + for (var ii = 0; ii < matches.length; ii++) { + var nag = matches[ii].substr(1); + if (NAG[nag] !== undefined) { + comment = comment.replace(new RegExp("\\$+" + nag + "(?!\\d)"), NAG[nag]); + } + } } - } - return comment; + return comment; } function ParseMove(move, plyCount) { - var ii, ll; - var rem; - var toRowMarker = -1; + var ii, ll; + var rem; + var toRowMarker = -1; - castleRook = -1; - mvIsCastling = 0; - mvIsPromotion = 0; - mvCapture = 0; - mvFromCol = -1; - mvFromRow = -1; - mvToCol = -1; - mvToRow = -1; - mvPiece = -1; - mvPieceId = -1; - mvPieceOnTo = -1; - mvCaptured = -1; - mvCapturedId = -1; - mvIsNull = 0; + castleRook = -1; + mvIsCastling = 0; + mvIsPromotion = 0; + mvCapture = 0; + mvFromCol = -1; + mvFromRow = -1; + mvToCol = -1; + mvToRow = -1; + mvPiece = -1; + mvPieceId = -1; + mvPieceOnTo = -1; + mvCaptured = -1; + mvCapturedId = -1; + mvIsNull = 0; - if (typeof(move) == "undefined") { return false; } - - HistEnPassant[plyCount+1] = false; - HistEnPassantCol[plyCount+1] = -1; - - if (move.indexOf('--') === 0) { - mvIsNull = 1; - CheckLegality('--', plyCount); - return true; - } - - // get destination column/row remembering what's left e.g. Rdxc3 exf8=Q# - for (ii = move.length-1; ii > 0; ii--) { - if (!isNaN(move.charAt(ii))) { - mvToCol = move.charCodeAt(ii-1) - 97; - mvToRow = move.charAt(ii) - 1; - rem = move.substring(0, ii-1); - toRowMarker = ii; - break; - } - } - - // final square did not make sense: maybe a castle? - if ((mvToCol < 0) || (mvToCol > 7) || (mvToRow < 0) || (mvToRow > 7)) { - // long castling first: looking for o-o will get o-o-o too - if (move.indexOf('O-O-O') === 0) { - mvIsCastling = 1; - mvPiece = 1; - mvPieceId = 0; - mvPieceOnTo = 1; - mvFromCol = 4; - mvToCol = 2; - mvFromRow = 7*MoveColor; - mvToRow = 7*MoveColor; - return CheckLegality('O-O-O', plyCount); - } else if (move.indexOf('O-O') === 0) { - mvIsCastling = 1; - mvPiece = 1; - mvPieceId = 0; - mvPieceOnTo = 1; - mvFromCol = 4; - mvToCol = 6; - mvFromRow = 7*MoveColor; - mvToRow = 7*MoveColor; - return CheckLegality('O-O', plyCount); - } else { return false; } - } - - rem = rem.replace(/-/g, ''); - // get piece and origin square: mark captures ('x' is there) - ll = rem.length; - if (ll > 4) { return false; } - mvPiece = -1; // make sure mvPiece is properly assigned later - if (ll === 0) { mvPiece = 6; } - else { - for (ii = 5; ii > 0; ii--) { if (rem.charAt(0) == PiecesArr[ii-1]) { mvPiece = ii; break; } } - if (mvPiece == -1) { if (columnsLetters.toLowerCase().indexOf(rem.charAt(0)) >= 0) { mvPiece = 6; } } - if (mvPiece == -1) { return false; } - if (rem.charAt(ll-1) == 'x') { mvCapture = 1; } - if (isNaN(move.charAt(ll-1-mvCapture))) { - mvFromCol = move.charCodeAt(ll-1-mvCapture) - 97; - if ((mvFromCol < 0) || (mvFromCol > 7)) { mvFromCol = -1; } - } else { - mvFromRow = move.charAt(ll-1-mvCapture) - 1; - if ((mvFromRow < 0) || (mvFromRow > 7)) { mvFromRow = -1; } - else { - mvFromCol = move.charCodeAt(ll-2-mvCapture) - 97; - if ((mvFromCol < 0) || (mvFromCol > 7)) { mvFromCol = -1; } - } + if (typeof (move) == "undefined") { + return false; } - if ( (ll > 1) && (!mvCapture) && (mvFromCol == -1) && (mvFromRow == -1) ) { return false; } - if ( (mvPiece == 6) && (!mvCapture) && (mvFromCol == -1) && (mvFromRow == -1) ) { return false; } - } + HistEnPassant[plyCount + 1] = false; + HistEnPassantCol[plyCount + 1] = -1; - // "square to" occupied: capture (note en-passant case) - if ((Board[mvToCol][mvToRow] !== 0) || ((mvPiece == 6) && (HistEnPassant[plyCount]) && (mvToCol == HistEnPassantCol[plyCount]) && (mvToRow == 5-3*MoveColor))) { mvCapture = 1; } - - mvPieceOnTo = mvPiece; - if (mvPiece == 6) { - // move contains '=' or char after destination row: might be a promotion - ii = move.indexOf('='); - if (ii < 0) { ii = toRowMarker; } - if ((ii > 0) && (ii < move.length-1)) { - var newPiece = move.charAt(ii+1); - if (newPiece == PiecesArr[1]) { mvPieceOnTo = 2; } - else if (newPiece == PiecesArr[2]) { mvPieceOnTo = 3; } - else if (newPiece == PiecesArr[3]) { mvPieceOnTo = 4; } - else if (newPiece == PiecesArr[4]) { mvPieceOnTo = 5; } - if (mvPieceOnTo != mvPiece) { mvIsPromotion = 1; } + if (move.indexOf('--') === 0) { + mvIsNull = 1; + CheckLegality('--', plyCount); + return true; } - if ((mvToRow == 7 * (1-MoveColor)) ? !mvIsPromotion : mvIsPromotion) { return false; } - } - // which captured piece: if nothing found must be en-passant - if (mvCapture) { - for (mvCapturedId = 15; mvCapturedId >= 0; mvCapturedId--) { - if ((PieceType[1-MoveColor][mvCapturedId] > 0) && (PieceCol[1-MoveColor][mvCapturedId] == mvToCol) && (PieceRow[1-MoveColor][mvCapturedId] == mvToRow)) { - mvCaptured = PieceType[1-MoveColor][mvCapturedId]; - if (mvCaptured == 1) { return false; } - break; - } - } - if ((mvPiece == 6) && (mvCapturedId < 1) && (HistEnPassant[plyCount])) { - for (mvCapturedId = 15; mvCapturedId >= 0; mvCapturedId--) { - if ((PieceType[1-MoveColor][mvCapturedId] == 6) && (PieceCol[1-MoveColor][mvCapturedId] == mvToCol) && (PieceRow[1-MoveColor][mvCapturedId] == 4-MoveColor)) { - mvCaptured = PieceType[1-MoveColor][mvCapturedId]; - break; + // get destination column/row remembering what's left e.g. Rdxc3 exf8=Q# + for (ii = move.length - 1; ii > 0; ii--) { + if (!isNaN(move.charAt(ii))) { + mvToCol = move.charCodeAt(ii - 1) - 97; + mvToRow = move.charAt(ii) - 1; + rem = move.substring(0, ii - 1); + toRowMarker = ii; + break; } - } } - } - // check move legality - if (!CheckLegality(PiecesArr[mvPiece-1], plyCount)) { return false; } + // final square did not make sense: maybe a castle? + if ((mvToCol < 0) || (mvToCol > 7) || (mvToRow < 0) || (mvToRow > 7)) { + // long castling first: looking for o-o will get o-o-o too + if (move.indexOf('O-O-O') === 0) { + mvIsCastling = 1; + mvPiece = 1; + mvPieceId = 0; + mvPieceOnTo = 1; + mvFromCol = 4; + mvToCol = 2; + mvFromRow = 7 * MoveColor; + mvToRow = 7 * MoveColor; + return CheckLegality('O-O-O', plyCount); + } else if (move.indexOf('O-O') === 0) { + mvIsCastling = 1; + mvPiece = 1; + mvPieceId = 0; + mvPieceOnTo = 1; + mvFromCol = 4; + mvToCol = 6; + mvFromRow = 7 * MoveColor; + mvToRow = 7 * MoveColor; + return CheckLegality('O-O', plyCount); + } else { + return false; + } + } - // pawn moved: check en-passant possibility - if (mvPiece == 6) { - if (Math.abs(HistRow[0][plyCount]-mvToRow) == 2) { - HistEnPassant[plyCount+1] = true; - HistEnPassantCol[plyCount+1] = mvToCol; - } - } - return true; + rem = rem.replace(/-/g, ''); + // get piece and origin square: mark captures ('x' is there) + ll = rem.length; + if (ll > 4) { + return false; + } + mvPiece = -1; // make sure mvPiece is properly assigned later + if (ll === 0) { + mvPiece = 6; + } else { + for (ii = 5; ii > 0; ii--) { + if (rem.charAt(0) == PiecesArr[ii - 1]) { + mvPiece = ii; + break; + } + } + if (mvPiece == -1) { + if (columnsLetters.toLowerCase().indexOf(rem.charAt(0)) >= 0) { + mvPiece = 6; + } + } + if (mvPiece == -1) { + return false; + } + if (rem.charAt(ll - 1) == 'x') { + mvCapture = 1; + } + if (isNaN(move.charAt(ll - 1 - mvCapture))) { + mvFromCol = move.charCodeAt(ll - 1 - mvCapture) - 97; + if ((mvFromCol < 0) || (mvFromCol > 7)) { + mvFromCol = -1; + } + } else { + mvFromRow = move.charAt(ll - 1 - mvCapture) - 1; + if ((mvFromRow < 0) || (mvFromRow > 7)) { + mvFromRow = -1; + } else { + mvFromCol = move.charCodeAt(ll - 2 - mvCapture) - 97; + if ((mvFromCol < 0) || (mvFromCol > 7)) { + mvFromCol = -1; + } + } + } + + if ((ll > 1) && (!mvCapture) && (mvFromCol == -1) && (mvFromRow == -1)) { + return false; + } + if ((mvPiece == 6) && (!mvCapture) && (mvFromCol == -1) && (mvFromRow == -1)) { + return false; + } + } + + // "square to" occupied: capture (note en-passant case) + if ((Board[mvToCol][mvToRow] !== 0) || ((mvPiece == 6) && (HistEnPassant[plyCount]) && (mvToCol == HistEnPassantCol[plyCount]) && (mvToRow == 5 - 3 * MoveColor))) { + mvCapture = 1; + } + + mvPieceOnTo = mvPiece; + if (mvPiece == 6) { + // move contains '=' or char after destination row: might be a promotion + ii = move.indexOf('='); + if (ii < 0) { + ii = toRowMarker; + } + if ((ii > 0) && (ii < move.length - 1)) { + var newPiece = move.charAt(ii + 1); + if (newPiece == PiecesArr[1]) { + mvPieceOnTo = 2; + } else if (newPiece == PiecesArr[2]) { + mvPieceOnTo = 3; + } else if (newPiece == PiecesArr[3]) { + mvPieceOnTo = 4; + } else if (newPiece == PiecesArr[4]) { + mvPieceOnTo = 5; + } + if (mvPieceOnTo != mvPiece) { + mvIsPromotion = 1; + } + } + if ((mvToRow == 7 * (1 - MoveColor)) ? !mvIsPromotion : mvIsPromotion) { + return false; + } + } + + // which captured piece: if nothing found must be en-passant + if (mvCapture) { + for (mvCapturedId = 15; mvCapturedId >= 0; mvCapturedId--) { + if ((PieceType[1 - MoveColor][mvCapturedId] > 0) && (PieceCol[1 - MoveColor][mvCapturedId] == mvToCol) && (PieceRow[1 - MoveColor][mvCapturedId] == mvToRow)) { + mvCaptured = PieceType[1 - MoveColor][mvCapturedId]; + if (mvCaptured == 1) { + return false; + } + break; + } + } + if ((mvPiece == 6) && (mvCapturedId < 1) && (HistEnPassant[plyCount])) { + for (mvCapturedId = 15; mvCapturedId >= 0; mvCapturedId--) { + if ((PieceType[1 - MoveColor][mvCapturedId] == 6) && (PieceCol[1 - MoveColor][mvCapturedId] == mvToCol) && (PieceRow[1 - MoveColor][mvCapturedId] == 4 - MoveColor)) { + mvCaptured = PieceType[1 - MoveColor][mvCapturedId]; + break; + } + } + } + } + + // check move legality + if (!CheckLegality(PiecesArr[mvPiece - 1], plyCount)) { + return false; + } + + // pawn moved: check en-passant possibility + if (mvPiece == 6) { + if (Math.abs(HistRow[0][plyCount] - mvToRow) == 2) { + HistEnPassant[plyCount + 1] = true; + HistEnPassantCol[plyCount + 1] = mvToCol; + } + } + return true; } function SetGameSelectorOptions(head, num, chEvent, chSite, chRound, chWhite, chBlack, chResult, chDate) { - if (typeof(head) == "string") { gameSelectorHead = head; } - gameSelectorNum = (num === true); - gameSelectorChEvent = Math.max(Math.min(chEvent , 32) || 0, 0) || 0; - gameSelectorChSite = Math.max(Math.min(chSite , 32) || 0, 0) || 0; - gameSelectorChRound = Math.max(Math.min(chRound , 32) || 0, 0) || 0; - gameSelectorChWhite = Math.max(Math.min(chWhite , 32) || 0, 0) || 0; - gameSelectorChBlack = Math.max(Math.min(chBlack , 32) || 0, 0) || 0; - gameSelectorChResult = Math.max(Math.min(chResult, 32) || 0, 0) || 0; - gameSelectorChDate = Math.max(Math.min(chDate , 32) || 0, 0) || 0; + if (typeof (head) == "string") { + gameSelectorHead = head; + } + gameSelectorNum = (num === true); + gameSelectorChEvent = Math.max(Math.min(chEvent, 32) || 0, 0) || 0; + gameSelectorChSite = Math.max(Math.min(chSite, 32) || 0, 0) || 0; + gameSelectorChRound = Math.max(Math.min(chRound, 32) || 0, 0) || 0; + gameSelectorChWhite = Math.max(Math.min(chWhite, 32) || 0, 0) || 0; + gameSelectorChBlack = Math.max(Math.min(chBlack, 32) || 0, 0) || 0; + gameSelectorChResult = Math.max(Math.min(chResult, 32) || 0, 0) || 0; + gameSelectorChDate = Math.max(Math.min(chDate, 32) || 0, 0) || 0; } var clickedSquareInterval = null; + function clickedSquare(ii, jj) { - if (clickedSquareInterval) { return; } // dont trigger twice - var squareId = 'tcol' + jj + 'trow' + ii; - var theObj = document.getElementById(squareId); - if (theObj) { - var oldClass = theObj.className; - theObj.className = (ii+jj)%2 === 0 ? "blackSquare" : "whiteSquare"; - clickedSquareInterval = setTimeout("reset_after_click(" + ii + "," + jj + ",'" + oldClass + "','" + theObj.className + "')", 66); - clearSelectedText(); - } + if (clickedSquareInterval) { + return; + } // dont trigger twice + var squareId = 'tcol' + jj + 'trow' + ii; + var theObj = document.getElementById(squareId); + if (theObj) { + var oldClass = theObj.className; + theObj.className = (ii + jj) % 2 === 0 ? "blackSquare" : "whiteSquare"; + clickedSquareInterval = setTimeout("reset_after_click(" + ii + "," + jj + ",'" + oldClass + "','" + theObj.className + "')", 66); + clearSelectedText(); + } } -function reset_after_click (ii, jj, oldClass, newClass) { - var theObj = document.getElementById('tcol' + jj + 'trow' + ii); - if (theObj) { - // square class changed again by pgn4web already: dont touch it anymore e.g. autoplay - if (theObj.className == newClass) { theObj.className = oldClass; } - clickedSquareInterval = null; - } +function reset_after_click(ii, jj, oldClass, newClass) { + var theObj = document.getElementById('tcol' + jj + 'trow' + ii); + if (theObj) { + // square class changed again by pgn4web already: dont touch it anymore e.g. autoplay + if (theObj.className == newClass) { + theObj.className = oldClass; + } + clickedSquareInterval = null; + } } var lastSearchPgnExpression = ""; + function gameNumberSearchPgn(searchExpression, backward, includeCurrent) { - lastSearchPgnExpression = searchExpression; - if (searchExpression === "") { return false; } - // replace newline with spaces so that we can use regexp "." on whole game - var newlinesRegExp = new RegExp("[\n\r]", "gm"); - var searchExpressionRegExp = new RegExp(searchExpression, "im"); - // at start currentGame might still be -1 - var thisCurrentGame = (currentGame < 0) || (currentGame >= numberOfGames) ? 0 : currentGame; - var needle = fullPgnGame(thisCurrentGame); - if (includeCurrent && needle.replace(newlinesRegExp, " ").match(searchExpressionRegExp)) { - return thisCurrentGame; - } - var delta = backward ? -1 : +1; - for (var thisGame = (thisCurrentGame + delta + numberOfGames) % numberOfGames; thisGame != thisCurrentGame; thisGame = (thisGame + delta + numberOfGames) % numberOfGames) { - needle = fullPgnGame(thisGame); - if (needle.replace(newlinesRegExp, " ").match(searchExpressionRegExp)) { - return thisGame; + lastSearchPgnExpression = searchExpression; + if (searchExpression === "") { + return false; } - } - return false; + // replace newline with spaces so that we can use regexp "." on whole game + var newlinesRegExp = new RegExp("[\n\r]", "gm"); + var searchExpressionRegExp = new RegExp(searchExpression, "im"); + // at start currentGame might still be -1 + var thisCurrentGame = (currentGame < 0) || (currentGame >= numberOfGames) ? 0 : currentGame; + var needle = fullPgnGame(thisCurrentGame); + if (includeCurrent && needle.replace(newlinesRegExp, " ").match(searchExpressionRegExp)) { + return thisCurrentGame; + } + var delta = backward ? -1 : +1; + for (var thisGame = (thisCurrentGame + delta + numberOfGames) % numberOfGames; thisGame != thisCurrentGame; thisGame = (thisGame + delta + numberOfGames) % numberOfGames) { + needle = fullPgnGame(thisGame); + if (needle.replace(newlinesRegExp, " ").match(searchExpressionRegExp)) { + return thisGame; + } + } + return false; } function searchPgnGame(searchExpression, backward) { - if (typeof(searchExpression) == "undefined") { searchExpression = ""; } - lastSearchPgnExpression = searchExpression; - var theObj = document.getElementById('searchPgnExpression'); - if (theObj) { theObj.value = searchExpression; } - if ((searchExpression === "") || (numberOfGames < 2)) { return; } - var thisGame = gameNumberSearchPgn(searchExpression, backward, false); - if ((thisGame !== false) && (thisGame != currentGame)) { Init(thisGame); } + if (typeof (searchExpression) == "undefined") { + searchExpression = ""; + } + lastSearchPgnExpression = searchExpression; + var theObj = document.getElementById('searchPgnExpression'); + if (theObj) { + theObj.value = searchExpression; + } + if ((searchExpression === "") || (numberOfGames < 2)) { + return; + } + var thisGame = gameNumberSearchPgn(searchExpression, backward, false); + if ((thisGame !== false) && (thisGame != currentGame)) { + Init(thisGame); + } } function searchPgnGamePrompt() { - if (numberOfGames < 2) { - alert("info: search prompt disabled with less than 2 games"); - return; - } - var searchExpression = prompt("Please enter search pattern for PGN games:", lastSearchPgnExpression); - if (searchExpression) { searchPgnGame(searchExpression); } + if (numberOfGames < 2) { + alert("info: search prompt disabled with less than 2 games"); + return; + } + var searchExpression = prompt("Please enter search pattern for PGN games:", lastSearchPgnExpression); + if (searchExpression) { + searchPgnGame(searchExpression); + } } function searchPgnGameForm() { - var theObj = document.getElementById('searchPgnExpression'); - if (theObj) { searchPgnGame(document.getElementById('searchPgnExpression').value); } + var theObj = document.getElementById('searchPgnExpression'); + if (theObj) { + searchPgnGame(document.getElementById('searchPgnExpression').value); + } } var chessMovesRegExp = new RegExp("\\b((\\d+(\\.{1,3}|\\s)\\s*)?((([KQRBN][a-h1-8]?)|[a-h])?x?[a-h][1-8](=[QRNB])?|O-O-O|O-O)\\b[!?+#]*)", "g"); + function fixCommentForDisplay(comment) { - return comment.replace(chessMovesRegExp, '$1'); + return comment.replace(chessMovesRegExp, '$1'); } var tableSize = 0; var textSelectOptions = ''; + function PrintHTML(forceBoardUpdate) { - var ii, jj, text, theObj, squareId, imageId, squareCoord, squareTitle, numText, textSO; + var ii, jj, text, theObj, squareId, imageId, squareCoord, squareTitle, numText, textSO; - // chessboard + // chessboard - if (theObj = document.getElementById("GameBoard")) { - if (forceBoardUpdate || !document.getElementById("boardTable")) { - text = ' 0) ? ' STYLE="width: ' + tableSize + 'px; height: ' + tableSize + 'px;">' : '>'; - for (ii = 0; ii < 8; ++ii) { - text += ''; - for (jj = 0; jj < 8; ++jj) { - squareId = 'tcol' + jj + 'trow' + ii; - imageId = 'img_' + squareId; - text += (ii+jj)%2 === 0 ? ''; + if (theObj = document.getElementById("GameBoard")) { + if (forceBoardUpdate || !document.getElementById("boardTable")) { + text = '
'; - squareCoord = IsRotated ? String.fromCharCode(72-jj,49+ii) : String.fromCharCode(jj+65,56-ii); - squareTitle = squareCoord; - if (boardTitle[jj][ii] !== '') { squareTitle += ': ' + boardTitle[jj][ii]; } - text += '
0) ? ' STYLE="width: ' + tableSize + 'px; height: ' + tableSize + 'px;">' : '>'; + for (ii = 0; ii < 8; ++ii) { + text += ''; + for (jj = 0; jj < 8; ++jj) { + squareId = 'tcol' + jj + 'trow' + ii; + imageId = 'img_' + squareId; + text += (ii + jj) % 2 === 0 ? ''; + } + text += ''; + } + text += '
'; + squareCoord = IsRotated ? String.fromCharCode(72 - jj, 49 + ii) : String.fromCharCode(jj + 65, 56 - ii); + squareTitle = squareCoord; + if (boardTitle[jj][ii] !== '') { + squareTitle += ': ' + boardTitle[jj][ii]; + } + text += '
'; + + theObj.innerHTML = text; } - text += ''; - } - text += ''; - - theObj.innerHTML = text; } - } - if (theObj = document.getElementById("boardTable")) { - tableSize = theObj.offsetWidth; - if (tableSize > 0) { // coping with browser always returning 0 to offsetWidth - theObj.style.height = tableSize + "px"; - } - } - - // control buttons - - if (theObj = document.getElementById("GameButtons")) { - var numButtons = 5; - var spaceSize = 3; - var buttonSize = (tableSize - spaceSize*(numButtons - 1)) / numButtons; - text = '
'; - text += '
'; - - theObj.innerHTML = text; - } - - // game selector - - if (theObj = document.getElementById("GameSelector")) { - if (firstStart) { textSelectOptions=''; } - if (numberOfGames < 2) { - while (theObj.firstChild) { theObj.removeChild(theObj.firstChild); } - textSelectOptions = ''; - } else { - if (textSelectOptions === '') { - if (gameSelectorNum) { gameSelectorNumLenght = Math.floor(Math.log(numberOfGames)/Math.log(10)) + 1; } - text = '
'; // see function simpleHtmlentities() + } + + // control buttons + + if (theObj = document.getElementById("GameButtons")) { + var numButtons = 5; + var spaceSize = 3; + var buttonSize = (tableSize - spaceSize * (numButtons - 1)) / numButtons; + text = '
'; + text += '
'; + theObj.innerHTML = text; - } } - } - // game event + // game selector - if (theObj = document.getElementById("GameEvent")) { theObj.innerHTML = gameEvent[currentGame]; } + if (theObj = document.getElementById("GameSelector")) { + if (firstStart) { + textSelectOptions = ''; + } + if (numberOfGames < 2) { + while (theObj.firstChild) { + theObj.removeChild(theObj.firstChild); + } + textSelectOptions = ''; + } else { + if (textSelectOptions === '') { + if (gameSelectorNum) { + gameSelectorNumLenght = Math.floor(Math.log(numberOfGames) / Math.log(10)) + 1; + } + text = '
'; - theObj.innerHTML = text; - theObj = document.getElementById('searchPgnExpression'); - if (theObj) { theObj.value = lastSearchPgnExpression; } + for (ii = 0; ii < numberOfGames; ii++) { + textSelectOptions += '
' + text + ''; } - } else { text = ''; } - return text; + if (typeof (addHtmlTags) == "undefined") { + addHtmlTags = false; + } + var varId = variationTag.replace(pgn4webVariationRegExp, "$1"); + if (isNaN(varId)) { + myAlert("error: issue parsing variation tag " + variationTag + " in game " + (currentGame + 1), true); + return ""; + } + var text = variationTextFromId(varId); + if (text) { + if (addHtmlTags) { + text = '' + text + ''; + } + } else { + text = ''; + } + return text; } var variationTextDepth, printedComment, printedVariation; + function variationTextFromId(varId) { - var punctChars = ",.;:!?", thisComment; + var punctChars = ",.;:!?", thisComment; - if (isNaN(varId) || varId < 0 || varId >= numberOfVars || typeof(StartPlyVar[varId]) == "undefined" || typeof(PlyNumberVar[varId]) == "undefined") { - myAlert("error: issue parsing variation id " + varId + " in game " + (currentGame+1), true); - return ""; - } - var text = ++variationTextDepth ? ('' + (printedVariation ? ' ' : '') + (variationTextDepth > 1 ? '(' : '[')) + '' : ''; - printedVariation = false; - for (var ii = StartPlyVar[varId]; ii < StartPlyVar[varId] + PlyNumberVar[varId]; ii++) { - printedComment = false; - if (commentsIntoMoveText && (thisComment = strippedMoveComment(ii, varId, true))) { - if (commentsOnSeparateLines && variationTextDepth === 0 && ii > StartPlyVar[varId]) { - text += '
 
'; - } - if (printedVariation) { if (punctChars.indexOf(thisComment.charAt(0)) == -1) { text += ' '; } } - else { printedVariation = variationTextDepth > 0; } - text += '' + thisComment + ''; - if (commentsOnSeparateLines && variationTextDepth === 0) { - text += '
 
'; - } - printedComment = true; + if (isNaN(varId) || varId < 0 || varId >= numberOfVars || typeof (StartPlyVar[varId]) == "undefined" || typeof (PlyNumberVar[varId]) == "undefined") { + myAlert("error: issue parsing variation id " + varId + " in game " + (currentGame + 1), true); + return ""; } - if (printedComment || printedVariation) { text += ' '; } + var text = ++variationTextDepth ? ('' + (printedVariation ? ' ' : '') + (variationTextDepth > 1 ? '(' : '[')) + '' : ''; + printedVariation = false; + for (var ii = StartPlyVar[varId]; ii < StartPlyVar[varId] + PlyNumberVar[varId]; ii++) { + printedComment = false; + if (commentsIntoMoveText && (thisComment = strippedMoveComment(ii, varId, true))) { + if (commentsOnSeparateLines && variationTextDepth === 0 && ii > StartPlyVar[varId]) { + text += '
 
'; + } + if (printedVariation) { + if (punctChars.indexOf(thisComment.charAt(0)) == -1) { + text += ' '; + } + } else { + printedVariation = variationTextDepth > 0; + } + text += '' + thisComment + ''; + if (commentsOnSeparateLines && variationTextDepth === 0) { + text += '
 
'; + } + printedComment = true; + } + if (printedComment || printedVariation) { + text += ' '; + } + printedVariation = true; + + text += printMoveText(ii, varId, (variationTextDepth > 0), ((printedComment) || (ii == StartPlyVar[varId])), true); + } + if (commentsIntoMoveText && (thisComment = strippedMoveComment(StartPlyVar[varId] + PlyNumberVar[varId], varId, true))) { + if (commentsOnSeparateLines && variationTextDepth === 0) { + text += '
 
'; + } + if (printedVariation && (punctChars.indexOf(thisComment.charAt(0)) == -1)) { + text += ' '; + } + text += '' + thisComment + ''; + printedComment = true; + } + text += variationTextDepth-- ? ('' + (variationTextDepth ? ')' : ']') + '') : ''; printedVariation = true; - - text += printMoveText(ii, varId, (variationTextDepth > 0), ((printedComment) || (ii == StartPlyVar[varId])), true); - } - if (commentsIntoMoveText && (thisComment = strippedMoveComment(StartPlyVar[varId] + PlyNumberVar[varId], varId, true))) { - if (commentsOnSeparateLines && variationTextDepth === 0) { - text += '
 
'; - } - if (printedVariation && (punctChars.indexOf(thisComment.charAt(0)) == -1)) { text += ' '; } - text += '' + thisComment + ''; - printedComment = true; - } - text += variationTextDepth-- ? ('' + (variationTextDepth ? ')' : ']') + '') : ''; - printedVariation = true; - return text; + return text; } function printMoveText(thisPly, thisVar, isVar, hasLeadingNum, hasId) { - if (typeof(thisVar) == "undefined") { thisVar = CurrentVar; } - if (typeof(thisPly) == "undefined") { thisPly = CurrentPly; } - var text = ''; - - if (thisVar >= numberOfVars || thisPly < StartPlyVar[thisVar] || thisPly > StartPlyVar[thisVar] + PlyNumberVar[thisVar]) { - return text; - } - - var moveCount = Math.floor(thisPly/2)+1; - if (thisPly%2 === 0) { - text += '' + moveCount + '. '; - } else { - if (hasLeadingNum) { - text += '' + moveCount + '... '; + if (typeof (thisVar) == "undefined") { + thisVar = CurrentVar; } - } - var jj = thisPly+1; - text += '= numberOfVars || thisPly < StartPlyVar[thisVar] || thisPly > StartPlyVar[thisVar] + PlyNumberVar[thisVar]) { + return text; + } + + var moveCount = Math.floor(thisPly / 2) + 1; + if (thisPly % 2 === 0) { + text += '' + moveCount + '. '; + } else { + if (hasLeadingNum) { + text += '' + moveCount + '... '; + } + } + var jj = thisPly + 1; + text += ' theContainerObjOffsetVeryTop + theContainerObj.scrollTop + theContainerObj.clientHeight) || (theMoveObjOffsetVeryTop < theContainerObjOffsetVeryTop + theContainerObj.scrollTop)) { - theContainerObj.scrollTop = theMoveObjOffsetVeryTop - theContainerObjOffsetVeryTop; - } - } + if (!objId) { + return; + } + var theContainerObj = document.getElementById(objId); + if (theContainerObj) { + if (CurrentPly == StartPly) { + theContainerObj.scrollTop = 0; + } else { + var theMoveObj = document.getElementById('Var' + CurrentVar + 'Mv' + CurrentPly); + if (theMoveObj) { + var theContainerObjOffsetVeryTop = objOffsetVeryTop(theContainerObj); + var theMoveObjOffsetVeryTop = objOffsetVeryTop(theMoveObj); + if ((theMoveObjOffsetVeryTop + theMoveObj.offsetHeight > theContainerObjOffsetVeryTop + theContainerObj.scrollTop + theContainerObj.clientHeight) || (theMoveObjOffsetVeryTop < theContainerObjOffsetVeryTop + theContainerObj.scrollTop)) { + theContainerObj.scrollTop = theMoveObjOffsetVeryTop - theContainerObjOffsetVeryTop; + } + } + } } - } } function FlipBoard() { - var oldHighlightOption = highlightOption; - if (oldHighlightOption) { SetHighlight(false); } - IsRotated = !IsRotated; - PrintHTML(true); - RefreshBoard(); - if (oldHighlightOption) { SetHighlight(true); } + var oldHighlightOption = highlightOption; + if (oldHighlightOption) { + SetHighlight(false); + } + IsRotated = !IsRotated; + PrintHTML(true); + RefreshBoard(); + if (oldHighlightOption) { + SetHighlight(true); + } } function RefreshBoard() { - for (var jj = 0; jj < 8; ++jj) { - for (var ii = 0; ii < 8; ++ii) { - if (Board[jj][ii] === 0) { SetImage(jj, ii, ClearImg.src); } + for (var jj = 0; jj < 8; ++jj) { + for (var ii = 0; ii < 8; ++ii) { + if (Board[jj][ii] === 0) { + SetImage(jj, ii, ClearImg.src); + } + } } - } - for (jj = 0; jj < 2; ++jj) { - for (ii = 0; ii < 16; ++ii) { - if (PieceType[jj][ii] > 0) { - SetImage(PieceCol[jj][ii], PieceRow[jj][ii], PieceImg[jj][PieceType[jj][ii]].src); - } + for (jj = 0; jj < 2; ++jj) { + for (ii = 0; ii < 16; ++ii) { + if (PieceType[jj][ii] > 0) { + SetImage(PieceCol[jj][ii], PieceRow[jj][ii], PieceImg[jj][PieceType[jj][ii]].src); + } + } } - } } function SetAutoPlay(vv) { - isAutoPlayOn = vv; + isAutoPlayOn = vv; - if (AutoPlayInterval) { clearTimeout(AutoPlayInterval); AutoPlayInterval = null; } + if (AutoPlayInterval) { + clearTimeout(AutoPlayInterval); + AutoPlayInterval = null; + } - if (isAutoPlayOn) { - if (document.GameButtonsForm) { - if (document.GameButtonsForm.AutoPlay) { - document.GameButtonsForm.AutoPlay.value = "="; - document.GameButtonsForm.AutoPlay.title = "toggle autoplay (stop)"; - document.GameButtonsForm.AutoPlay.className = "buttonControlStop"; - } + if (isAutoPlayOn) { + if (document.GameButtonsForm) { + if (document.GameButtonsForm.AutoPlay) { + document.GameButtonsForm.AutoPlay.value = "="; + document.GameButtonsForm.AutoPlay.title = "toggle autoplay (stop)"; + document.GameButtonsForm.AutoPlay.className = "buttonControlStop"; + } + } + if (CurrentPly < StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]) { + AutoPlayInterval = setTimeout("MoveForward(1)", Delay); + } else { + if (autoplayNextGame && (CurrentVar === 0)) { + AutoPlayInterval = setTimeout("AutoplayNextGame()", Delay); + } else { + SetAutoPlay(false); + } + } + } else { + if (document.GameButtonsForm) { + if (document.GameButtonsForm.AutoPlay) { + document.GameButtonsForm.AutoPlay.value = "+"; + document.GameButtonsForm.AutoPlay.title = "toggle autoplay (start)"; + document.GameButtonsForm.AutoPlay.className = "buttonControlPlay"; + } + } } - if (CurrentPly < StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]) { AutoPlayInterval=setTimeout("MoveForward(1)", Delay); } - else { - if (autoplayNextGame && (CurrentVar === 0)) { AutoPlayInterval=setTimeout("AutoplayNextGame()", Delay); } - else { SetAutoPlay(false); } - } - } else { - if (document.GameButtonsForm) { - if (document.GameButtonsForm.AutoPlay) { - document.GameButtonsForm.AutoPlay.value = "+"; - document.GameButtonsForm.AutoPlay.title = "toggle autoplay (start)"; - document.GameButtonsForm.AutoPlay.className = "buttonControlPlay"; - } - } - } } var minAutoplayDelay = 500; var maxAutoplayDelay = 300000; + function setCustomAutoplayDelay() { - var newDelaySec = prompt("Enter custom autoplay delay, in seconds, between " + (minAutoplayDelay/1000) + " and " + (maxAutoplayDelay/1000) + ":", Math.floor(Delay / 100) / 10); - if (!isNaN(newDelaySec = parseInt(newDelaySec, 10))) { - SetAutoplayDelayAndStart(newDelaySec * 1000); - } + var newDelaySec = prompt("Enter custom autoplay delay, in seconds, between " + (minAutoplayDelay / 1000) + " and " + (maxAutoplayDelay / 1000) + ":", Math.floor(Delay / 100) / 10); + if (!isNaN(newDelaySec = parseInt(newDelaySec, 10))) { + SetAutoplayDelayAndStart(newDelaySec * 1000); + } } function SetAutoplayDelay(vv) { - if (isNaN(vv = parseInt(vv, 10))) { return; } - Delay = Math.min(Math.max(vv, minAutoplayDelay), maxAutoplayDelay); + if (isNaN(vv = parseInt(vv, 10))) { + return; + } + Delay = Math.min(Math.max(vv, minAutoplayDelay), maxAutoplayDelay); } function SetAutoplayDelayAndStart(vv) { - MoveForward(1); - SetAutoplayDelay(vv); - SetAutoPlay(true); + MoveForward(1); + SetAutoplayDelay(vv); + SetAutoPlay(true); } function SetLiveBroadcast(delay, alertFlag, demoFlag, stepFlag, endlessFlag) { - LiveBroadcastDelay = delay; // zero delay: no live broadcast - LiveBroadcastAlert = (alertFlag === true); - LiveBroadcastDemo = (demoFlag === true); - LiveBroadcastSteppingMode = (stepFlag === true); - LiveBroadcastEndlessMode = (endlessFlag === true); - setG7A6B6H7boardShortcuts(); + LiveBroadcastDelay = delay; // zero delay: no live broadcast + LiveBroadcastAlert = (alertFlag === true); + LiveBroadcastDemo = (demoFlag === true); + LiveBroadcastSteppingMode = (stepFlag === true); + LiveBroadcastEndlessMode = (endlessFlag === true); + setG7A6B6H7boardShortcuts(); } function SetImage(col, row, image) { - var trow = IsRotated ? row : 7 - row; - var tcol = IsRotated ? 7 - col : col; - var theObj = document.getElementById('img_' + 'tcol' + tcol + 'trow' + trow); - if ((theObj) && (theObj.src != image)) { theObj.src = image; } + var trow = IsRotated ? row : 7 - row; + var tcol = IsRotated ? 7 - col : col; + var theObj = document.getElementById('img_' + 'tcol' + tcol + 'trow' + trow); + if ((theObj) && (theObj.src != image)) { + theObj.src = image; + } } function SetImagePath(path) { - ImagePath = path; + ImagePath = path; } function SwitchAutoPlay() { - if (!isAutoPlayOn) { MoveForward(1); } - SetAutoPlay(!isAutoPlayOn); + if (!isAutoPlayOn) { + MoveForward(1); + } + SetAutoPlay(!isAutoPlayOn); } function StoreMove(thisPly) { - HistVar[thisPly+1] = CurrentVar; + HistVar[thisPly + 1] = CurrentVar; - if (HistNull[thisPly] = mvIsNull) { return; } + if (HistNull[thisPly] = mvIsNull) { + return; + } - // "square from" history - HistPieceId[0][thisPly] = mvPieceId; - HistCol[0][thisPly] = PieceCol[MoveColor][mvPieceId]; - HistRow[0][thisPly] = PieceRow[MoveColor][mvPieceId]; - HistType[0][thisPly] = PieceType[MoveColor][mvPieceId]; + // "square from" history + HistPieceId[0][thisPly] = mvPieceId; + HistCol[0][thisPly] = PieceCol[MoveColor][mvPieceId]; + HistRow[0][thisPly] = PieceRow[MoveColor][mvPieceId]; + HistType[0][thisPly] = PieceType[MoveColor][mvPieceId]; - // "square to" history - HistCol[2][thisPly] = mvToCol; - HistRow[2][thisPly] = mvToRow; + // "square to" history + HistCol[2][thisPly] = mvToCol; + HistRow[2][thisPly] = mvToRow; - if (mvIsCastling) { - HistPieceId[1][thisPly] = castleRook; - HistCol[1][thisPly] = PieceCol[MoveColor][castleRook]; - HistRow[1][thisPly] = PieceRow[MoveColor][castleRook]; - HistType[1][thisPly] = PieceType[MoveColor][castleRook]; - } else if (mvCapturedId >= 0) { - HistPieceId[1][thisPly] = mvCapturedId+16; - HistCol[1][thisPly] = PieceCol[1-MoveColor][mvCapturedId]; - HistRow[1][thisPly] = PieceRow[1-MoveColor][mvCapturedId]; - HistType[1][thisPly] = PieceType[1-MoveColor][mvCapturedId]; - } else { - HistPieceId[1][thisPly] = -1; - } + if (mvIsCastling) { + HistPieceId[1][thisPly] = castleRook; + HistCol[1][thisPly] = PieceCol[MoveColor][castleRook]; + HistRow[1][thisPly] = PieceRow[MoveColor][castleRook]; + HistType[1][thisPly] = PieceType[MoveColor][castleRook]; + } else if (mvCapturedId >= 0) { + HistPieceId[1][thisPly] = mvCapturedId + 16; + HistCol[1][thisPly] = PieceCol[1 - MoveColor][mvCapturedId]; + HistRow[1][thisPly] = PieceRow[1 - MoveColor][mvCapturedId]; + HistType[1][thisPly] = PieceType[1 - MoveColor][mvCapturedId]; + } else { + HistPieceId[1][thisPly] = -1; + } - // update "square from" and captured square (not "square to" for en-passant) - Board[PieceCol[MoveColor][mvPieceId]][PieceRow[MoveColor][mvPieceId]] = 0; + // update "square from" and captured square (not "square to" for en-passant) + Board[PieceCol[MoveColor][mvPieceId]][PieceRow[MoveColor][mvPieceId]] = 0; - // mark captured piece - if (mvCapturedId >= 0) { - PieceType[1-MoveColor][mvCapturedId] = -1; - PieceMoveCounter[1-MoveColor][mvCapturedId]++; - Board[PieceCol[1-MoveColor][mvCapturedId]][PieceRow[1-MoveColor][mvCapturedId]] = 0; - } + // mark captured piece + if (mvCapturedId >= 0) { + PieceType[1 - MoveColor][mvCapturedId] = -1; + PieceMoveCounter[1 - MoveColor][mvCapturedId]++; + Board[PieceCol[1 - MoveColor][mvCapturedId]][PieceRow[1 - MoveColor][mvCapturedId]] = 0; + } - // update piece arrays: promotion changes piece type - PieceType[MoveColor][mvPieceId] = mvPieceOnTo; - PieceMoveCounter[MoveColor][mvPieceId]++; - PieceCol[MoveColor][mvPieceId] = mvToCol; - PieceRow[MoveColor][mvPieceId] = mvToRow; - if (mvIsCastling) { - PieceMoveCounter[MoveColor][castleRook]++; - PieceCol[MoveColor][castleRook] = mvToCol == 2 ? 3 : 5; - PieceRow[MoveColor][castleRook] = mvToRow; - } + // update piece arrays: promotion changes piece type + PieceType[MoveColor][mvPieceId] = mvPieceOnTo; + PieceMoveCounter[MoveColor][mvPieceId]++; + PieceCol[MoveColor][mvPieceId] = mvToCol; + PieceRow[MoveColor][mvPieceId] = mvToRow; + if (mvIsCastling) { + PieceMoveCounter[MoveColor][castleRook]++; + PieceCol[MoveColor][castleRook] = mvToCol == 2 ? 3 : 5; + PieceRow[MoveColor][castleRook] = mvToRow; + } - // update board - Board[mvToCol][mvToRow] = PieceType[MoveColor][mvPieceId]*(1-2*MoveColor); - if (mvIsCastling) { - Board[PieceCol[MoveColor][castleRook]][PieceRow[MoveColor][castleRook]] = PieceType[MoveColor][castleRook]*(1-2*MoveColor); - } - return; + // update board + Board[mvToCol][mvToRow] = PieceType[MoveColor][mvPieceId] * (1 - 2 * MoveColor); + if (mvIsCastling) { + Board[PieceCol[MoveColor][castleRook]][PieceRow[MoveColor][castleRook]] = PieceType[MoveColor][castleRook] * (1 - 2 * MoveColor); + } + return; } function UndoMove(thisPly) { - if (HistNull[thisPly]) { return; } + if (HistNull[thisPly]) { + return; + } - // moved piece back to original square - var chgPiece = HistPieceId[0][thisPly]; - Board[PieceCol[MoveColor][chgPiece]][PieceRow[MoveColor][chgPiece]] = 0; - - Board[HistCol[0][thisPly]][HistRow[0][thisPly]] = HistType[0][thisPly] * (1-2*MoveColor); - PieceType[MoveColor][chgPiece] = HistType[0][thisPly]; - PieceCol[MoveColor][chgPiece] = HistCol[0][thisPly]; - PieceRow[MoveColor][chgPiece] = HistRow[0][thisPly]; - PieceMoveCounter[MoveColor][chgPiece]--; - - // castling: rook back to original square - chgPiece = HistPieceId[1][thisPly]; - if ((chgPiece >= 0) && (chgPiece < 16)) { + // moved piece back to original square + var chgPiece = HistPieceId[0][thisPly]; Board[PieceCol[MoveColor][chgPiece]][PieceRow[MoveColor][chgPiece]] = 0; - Board[HistCol[1][thisPly]][HistRow[1][thisPly]] = HistType[1][thisPly] * (1-2*MoveColor); - PieceType[MoveColor][chgPiece] = HistType[1][thisPly]; - PieceCol[MoveColor][chgPiece] = HistCol[1][thisPly]; - PieceRow[MoveColor][chgPiece] = HistRow[1][thisPly]; - PieceMoveCounter[MoveColor][chgPiece]--; - } - // capture: captured piece back to original square - chgPiece -= 16; - if ((chgPiece >= 0) && (chgPiece < 16)) { - Board[PieceCol[1-MoveColor][chgPiece]][PieceRow[1-MoveColor][chgPiece]] = 0; - Board[HistCol[1][thisPly]][HistRow[1][thisPly]] = HistType[1][thisPly] * (2*MoveColor-1); - PieceType[1-MoveColor][chgPiece] = HistType[1][thisPly]; - PieceCol[1-MoveColor][chgPiece] = HistCol[1][thisPly]; - PieceRow[1-MoveColor][chgPiece] = HistRow[1][thisPly]; - PieceMoveCounter[1-MoveColor][chgPiece]--; - } + Board[HistCol[0][thisPly]][HistRow[0][thisPly]] = HistType[0][thisPly] * (1 - 2 * MoveColor); + PieceType[MoveColor][chgPiece] = HistType[0][thisPly]; + PieceCol[MoveColor][chgPiece] = HistCol[0][thisPly]; + PieceRow[MoveColor][chgPiece] = HistRow[0][thisPly]; + PieceMoveCounter[MoveColor][chgPiece]--; + + // castling: rook back to original square + chgPiece = HistPieceId[1][thisPly]; + if ((chgPiece >= 0) && (chgPiece < 16)) { + Board[PieceCol[MoveColor][chgPiece]][PieceRow[MoveColor][chgPiece]] = 0; + Board[HistCol[1][thisPly]][HistRow[1][thisPly]] = HistType[1][thisPly] * (1 - 2 * MoveColor); + PieceType[MoveColor][chgPiece] = HistType[1][thisPly]; + PieceCol[MoveColor][chgPiece] = HistCol[1][thisPly]; + PieceRow[MoveColor][chgPiece] = HistRow[1][thisPly]; + PieceMoveCounter[MoveColor][chgPiece]--; + } + + // capture: captured piece back to original square + chgPiece -= 16; + if ((chgPiece >= 0) && (chgPiece < 16)) { + Board[PieceCol[1 - MoveColor][chgPiece]][PieceRow[1 - MoveColor][chgPiece]] = 0; + Board[HistCol[1][thisPly]][HistRow[1][thisPly]] = HistType[1][thisPly] * (2 * MoveColor - 1); + PieceType[1 - MoveColor][chgPiece] = HistType[1][thisPly]; + PieceCol[1 - MoveColor][chgPiece] = HistCol[1][thisPly]; + PieceRow[1 - MoveColor][chgPiece] = HistRow[1][thisPly]; + PieceMoveCounter[1 - MoveColor][chgPiece]--; + } } function Color(nn) { - if (nn < 0) { return 1; } - if (nn > 0) { return 0; } - return 2; + if (nn < 0) { + return 1; + } + if (nn > 0) { + return 0; + } + return 2; } function sign(nn) { - if (nn > 0) { return 1; } - if (nn < 0) { return -1; } - return 0; + if (nn > 0) { + return 1; + } + if (nn < 0) { + return -1; + } + return 0; } function SquareOnBoard(col, row) { - return col >= 0 && col <= 7 && row >= 0 && row <= 7; + return col >= 0 && col <= 7 && row >= 0 && row <= 7; } var pgn4webMaxTouches = 0; var pgn4webOngoingTouches = new Array(); + function pgn4webOngoingTouchIndexById(needle) { - var id; - for (var ii = 0; ii < pgn4webOngoingTouches.length; ii++) { - id = pgn4webOngoingTouches[ii].identifier; - if (pgn4webOngoingTouches[ii].identifier === needle) { return ii; } - } - return -1; + var id; + for (var ii = 0; ii < pgn4webOngoingTouches.length; ii++) { + id = pgn4webOngoingTouches[ii].identifier; + if (pgn4webOngoingTouches[ii].identifier === needle) { + return ii; + } + } + return -1; } function pgn4web_handleTouchStart(e) { - e.stopPropagation(); - for (var ii = 0; ii < e.changedTouches.length; ii++) { - pgn4webMaxTouches++; - pgn4webOngoingTouches.push({ identifier: e.changedTouches[ii].identifier, clientX: e.changedTouches[ii].clientX, clientY: e.changedTouches[ii].clientY }); - } + e.stopPropagation(); + for (var ii = 0; ii < e.changedTouches.length; ii++) { + pgn4webMaxTouches++; + pgn4webOngoingTouches.push({ + identifier: e.changedTouches[ii].identifier, + clientX: e.changedTouches[ii].clientX, + clientY: e.changedTouches[ii].clientY + }); + } } function pgn4web_handleTouchMove(e) { - e.stopPropagation(); - e.preventDefault(); + e.stopPropagation(); + e.preventDefault(); } function pgn4web_handleTouchEnd(e) { - e.stopPropagation(); - var jj; - for (var ii = 0; ii < e.changedTouches.length; ii++) { - if ((jj = pgn4webOngoingTouchIndexById(e.changedTouches[ii].identifier)) != -1) { - if (pgn4webOngoingTouches.length == 1) { - customFunctionOnTouch(e.changedTouches[ii].clientX - pgn4webOngoingTouches[jj].clientX, e.changedTouches[ii].clientY - pgn4webOngoingTouches[jj].clientY); - pgn4webMaxTouches = 0; - } - pgn4webOngoingTouches.splice(jj, 1); + e.stopPropagation(); + var jj; + for (var ii = 0; ii < e.changedTouches.length; ii++) { + if ((jj = pgn4webOngoingTouchIndexById(e.changedTouches[ii].identifier)) != -1) { + if (pgn4webOngoingTouches.length == 1) { + customFunctionOnTouch(e.changedTouches[ii].clientX - pgn4webOngoingTouches[jj].clientX, e.changedTouches[ii].clientY - pgn4webOngoingTouches[jj].clientY); + pgn4webMaxTouches = 0; + } + pgn4webOngoingTouches.splice(jj, 1); + } } - } - clearSelectedText(); + clearSelectedText(); } function pgn4web_handleTouchCancel(e) { - e.stopPropagation(); - var jj; - for (var ii = 0; ii < e.changedTouches.length; ii++) { - if ((jj = pgn4webOngoingTouchIndexById(e.changedTouches[ii].identifier)) != -1) { - pgn4webOngoingTouches.splice(jj, 1); - if (pgn4webOngoingTouches.length === 0) { pgn4webMaxTouches = 0; } + e.stopPropagation(); + var jj; + for (var ii = 0; ii < e.changedTouches.length; ii++) { + if ((jj = pgn4webOngoingTouchIndexById(e.changedTouches[ii].identifier)) != -1) { + pgn4webOngoingTouches.splice(jj, 1); + if (pgn4webOngoingTouches.length === 0) { + pgn4webMaxTouches = 0; + } + } } - } - clearSelectedText(); + clearSelectedText(); } function pgn4web_initTouchEvents() { - var theObj = document.getElementById("GameBoard"); - if (theObj && touchEventEnabled) { - simpleAddEvent(theObj, "touchstart", pgn4web_handleTouchStart); - simpleAddEvent(theObj, "touchmove", pgn4web_handleTouchMove); - simpleAddEvent(theObj, "touchend", pgn4web_handleTouchEnd); - simpleAddEvent(theObj, "touchleave", pgn4web_handleTouchEnd); - simpleAddEvent(theObj, "touchcancel", pgn4web_handleTouchCancel); - } + var theObj = document.getElementById("GameBoard"); + if (theObj && touchEventEnabled) { + simpleAddEvent(theObj, "touchstart", pgn4web_handleTouchStart); + simpleAddEvent(theObj, "touchmove", pgn4web_handleTouchMove); + simpleAddEvent(theObj, "touchend", pgn4web_handleTouchEnd); + simpleAddEvent(theObj, "touchleave", pgn4web_handleTouchEnd); + simpleAddEvent(theObj, "touchcancel", pgn4web_handleTouchCancel); + } } var waitForDoubleLeftTouchTimer = null; + function customFunctionOnTouch(deltaX, deltaY) { - if (Math.max(Math.abs(deltaX), Math.abs(deltaY)) < 13) { return; } - if (Math.abs(deltaY) > 1.5 * Math.abs(deltaX)) { // vertical up or down - if (numberOfGames > 1) { - if ((currentGame === 0) && (deltaY < 0)) { Init(numberOfGames - 1); } - else if ((currentGame === numberOfGames - 1) && (deltaY > 0)) { Init(0); } - else { Init(currentGame + sign(deltaY)); } + if (Math.max(Math.abs(deltaX), Math.abs(deltaY)) < 13) { + return; } - } else if (Math.abs(deltaX) > 1.5 * Math.abs(deltaY)) { - if (deltaX > 0) { // horizontal right - if (isAutoPlayOn) { GoToMove(StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]); } - else { SwitchAutoPlay(); } - } else { // horizontal left - if (isAutoPlayOn && !waitForDoubleLeftTouchTimer) { SwitchAutoPlay(); } - else { - if (waitForDoubleLeftTouchTimer) { - clearTimeout(waitForDoubleLeftTouchTimer); - waitForDoubleLeftTouchTimer = null; + if (Math.abs(deltaY) > 1.5 * Math.abs(deltaX)) { // vertical up or down + if (numberOfGames > 1) { + if ((currentGame === 0) && (deltaY < 0)) { + Init(numberOfGames - 1); + } else if ((currentGame === numberOfGames - 1) && (deltaY > 0)) { + Init(0); + } else { + Init(currentGame + sign(deltaY)); + } + } + } else if (Math.abs(deltaX) > 1.5 * Math.abs(deltaY)) { + if (deltaX > 0) { // horizontal right + if (isAutoPlayOn) { + GoToMove(StartPlyVar[CurrentVar] + PlyNumberVar[CurrentVar]); + } else { + SwitchAutoPlay(); + } + } else { // horizontal left + if (isAutoPlayOn && !waitForDoubleLeftTouchTimer) { + SwitchAutoPlay(); + } else { + if (waitForDoubleLeftTouchTimer) { + clearTimeout(waitForDoubleLeftTouchTimer); + waitForDoubleLeftTouchTimer = null; + } + if ((LiveBroadcastDelay > 0) && (CurrentVar === 0) && (CurrentPly === StartPly + PlyNumber)) { + waitForDoubleLeftTouchTimer = setTimeout("waitForDoubleLeftTouchTimer = null;", 900); + replayPreviousMoves(6); + } else { + GoToMove(StartPlyVar[CurrentVar] + (((CurrentPly <= StartPlyVar[CurrentVar] + 1) || (CurrentVar === 0)) ? 0 : 1)); + } + } } - if ((LiveBroadcastDelay > 0) && (CurrentVar === 0) && (CurrentPly === StartPly + PlyNumber)) { - waitForDoubleLeftTouchTimer = setTimeout("waitForDoubleLeftTouchTimer = null;", 900); - replayPreviousMoves(6); - } else { GoToMove(StartPlyVar[CurrentVar] + (((CurrentPly <= StartPlyVar[CurrentVar] + 1) || (CurrentVar === 0)) ? 0 : 1)); } - } } - } } -var touchGestures_helpActions = [ "chessboard top-down swipe", "chessboard bottom-up swipe", "chessboard left-right swipe", "chessboard right-left swipe" ]; -var touchGestures_helpText = [ "load next game, cycling through", "load previous game, cyclig through", "start autoplay; if autoplay already active: go to variation end or to game end", "stop autoplay; if autoplay not active: go to variation start, then to parent variation, then to game start; if at last move of live broadcast: replay up to 6 previous half-moves, then autoplay forward" ]; +var touchGestures_helpActions = ["chessboard top-down swipe", "chessboard bottom-up swipe", "chessboard left-right swipe", "chessboard right-left swipe"]; +var touchGestures_helpText = ["load next game, cycling through", "load previous game, cyclig through", "start autoplay; if autoplay already active: go to variation end or to game end", "stop autoplay; if autoplay not active: go to variation start, then to parent variation, then to game start; if at last move of live broadcast: replay up to 6 previous half-moves, then autoplay forward"]; var touchEventEnabled = true; + function SetTouchEventEnabled(onOff) { - touchEventEnabled = onOff; + touchEventEnabled = onOff; } function clearSelectedText() { - if (window.getSelection) { - if (window.getSelection().empty) { window.getSelection().empty(); } - else if (window.getSelection().removeAllRanges) { window.getSelection().removeAllRanges(); } - } else if (document.selection && document.selection.empty) { document.selection.empty(); } + if (window.getSelection) { + if (window.getSelection().empty) { + window.getSelection().empty(); + } else if (window.getSelection().removeAllRanges) { + window.getSelection().removeAllRanges(); + } + } else if (document.selection && document.selection.empty) { + document.selection.empty(); + } } function simpleHtmlentities(text) { - return text.replace(/&/g, "&").replace(//g, ">"); + return text.replace(/&/g, "&").replace(//g, ">"); } function simpleHtmlentitiesDecode(text) { - return text.replace(/>/g, ">").replace(/</g, "<").replace(/&/g, "&"); + return text.replace(/>/g, ">").replace(/</g, "<").replace(/&/g, "&"); } diff --git a/assets/svg/logo.svg b/assets/svg/logo.svg index f8c072a..054f6b1 100644 --- a/assets/svg/logo.svg +++ b/assets/svg/logo.svg @@ -1,12 +1,14 @@ - + - - + - + - - - - - Bad Steben - - 19 - - 82 - - -Schachfreunde + Bad Steben + + 19 + + 82 + + +Schachfreunde - + - - + - - + - - + - - + - - - - + - - - - + + - + -=8.0" - }, - "require-dev": { - "laravel/pint": "^1.5", - "phpstan/phpstan": "^1.10" - }, - "type": "library", - "autoload": { - "psr-0": { - "claviska": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Cory LaViska", - "homepage": "http://www.abeautifulsite.net/", - "role": "Developer" - } - ], - "description": "A PHP class that makes working with images as simple as possible.", - "support": { - "issues": "https://github.com/claviska/SimpleImage/issues", - "source": "https://github.com/claviska/SimpleImage/tree/4.2.1" - }, - "funding": [ - { - "url": "https://github.com/claviska", - "type": "github" - } - ], - "time": "2024-11-22T13:25:03+00:00" - }, - { - "name": "composer/semver", - "version": "3.4.3", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.11", - "symfony/phpunit-bridge": "^3 || ^7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "validation", - "versioning" - ], - "support": { - "irc": "ircs://irc.libera.chat:6697/composer", - "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.3" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2024-09-19T14:15:21+00:00" - }, - { - "name": "filp/whoops", - "version": "2.18.3", - "source": { - "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "59a123a3d459c5a23055802237cb317f609867e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/59a123a3d459c5a23055802237cb317f609867e5", - "reference": "59a123a3d459c5a23055802237cb317f609867e5", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^4.0 || ^5.0" - }, - "suggest": { - "symfony/var-dumper": "Pretty print complex values better with var-dumper available", - "whoops/soap": "Formats errors as SOAP responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Whoops\\": "src/Whoops/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" - } - ], - "description": "php error handling for cool kids", - "homepage": "https://filp.github.io/whoops/", - "keywords": [ - "error", - "exception", - "handling", - "library", - "throwable", - "whoops" - ], - "support": { - "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.18.3" - }, - "funding": [ - { - "url": "https://github.com/denis-sokolov", - "type": "github" - } - ], - "time": "2025-06-16T00:02:10+00:00" - }, - { - "name": "getkirby/cms", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/getkirby/kirby.git", - "reference": "2ff182ba39ddea19fa1615bd3733f734b5e53842" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/getkirby/kirby/zipball/2ff182ba39ddea19fa1615bd3733f734b5e53842", - "reference": "2ff182ba39ddea19fa1615bd3733f734b5e53842", - "shasum": "" - }, - "require": { - "christian-riesen/base32": "1.6.0", - "claviska/simpleimage": "4.2.1", - "composer/semver": "3.4.3", - "ext-ctype": "*", - "ext-curl": "*", - "ext-dom": "*", - "ext-filter": "*", - "ext-hash": "*", - "ext-iconv": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-openssl": "*", - "ext-simplexml": "*", - "filp/whoops": "2.18.3", - "getkirby/composer-installer": "^1.2.1", - "laminas/laminas-escaper": "2.17.0", - "michelf/php-smartypants": "1.8.1", - "php": "~8.2.0 || ~8.3.0 || ~8.4.0", - "phpmailer/phpmailer": "6.10.0", - "symfony/polyfill-intl-idn": "1.32.0", - "symfony/polyfill-mbstring": "1.32.0", - "symfony/yaml": "7.3.0" - }, - "replace": { - "symfony/polyfill-php72": "*" - }, - "suggest": { - "ext-PDO": "Support for using databases", - "ext-apcu": "Support for the Apcu cache driver", - "ext-exif": "Support for exif information from images", - "ext-fileinfo": "Improved mime type detection for files", - "ext-intl": "Improved i18n number formatting", - "ext-memcached": "Support for the Memcached cache driver", - "ext-redis": "Support for the Redis cache driver", - "ext-sodium": "Support for the crypto class and more robust session handling", - "ext-zip": "Support for ZIP archive file functions", - "ext-zlib": "Sanitization and validation for svgz files" - }, - "type": "kirby-cms", - "extra": { - "unused": [ - "symfony/polyfill-intl-idn" - ] - }, - "autoload": { - "files": [ - "config/setup.php", - "config/helpers.php" - ], - "psr-4": { - "Kirby\\": "src/" - }, - "classmap": [ - "dependencies/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "proprietary" - ], - "authors": [ - { - "name": "Kirby Team", - "email": "support@getkirby.com", - "homepage": "https://getkirby.com" - } - ], - "description": "The Kirby core", - "homepage": "https://getkirby.com", - "keywords": [ - "cms", - "core", - "kirby" - ], - "support": { - "email": "support@getkirby.com", - "forum": "https://forum.getkirby.com", - "issues": "https://github.com/getkirby/kirby/issues", - "source": "https://github.com/getkirby/kirby" - }, - "funding": [ - { - "url": "https://getkirby.com/buy", - "type": "custom" - } - ], - "time": "2025-06-24T07:42:42+00:00" - }, - { - "name": "getkirby/composer-installer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/getkirby/composer-installer.git", - "reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/getkirby/composer-installer/zipball/c98ece30bfba45be7ce457e1102d1b169d922f3d", - "reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0" - }, - "require-dev": { - "composer/composer": "^1.8 || ^2.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Kirby\\ComposerInstaller\\Plugin" - }, - "autoload": { - "psr-4": { - "Kirby\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Kirby's custom Composer installer for the Kirby CMS and for Kirby plugins", - "homepage": "https://getkirby.com", - "support": { - "issues": "https://github.com/getkirby/composer-installer/issues", - "source": "https://github.com/getkirby/composer-installer/tree/1.2.1" - }, - "funding": [ - { - "url": "https://getkirby.com/buy", - "type": "custom" - } - ], - "time": "2020-12-28T12:54:39+00:00" - }, - { - "name": "laminas/laminas-escaper", - "version": "2.17.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-escaper.git", - "reference": "df1ef9503299a8e3920079a16263b578eaf7c3ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/df1ef9503299a8e3920079a16263b578eaf7c3ba", - "reference": "df1ef9503299a8e3920079a16263b578eaf7c3ba", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-mbstring": "*", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" - }, - "conflict": { - "zendframework/zend-escaper": "*" - }, - "require-dev": { - "infection/infection": "^0.29.8", - "laminas/laminas-coding-standard": "~3.0.1", - "phpunit/phpunit": "^10.5.45", - "psalm/plugin-phpunit": "^0.19.2", - "vimeo/psalm": "^6.6.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Escaper\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", - "homepage": "https://laminas.dev", - "keywords": [ - "escaper", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-escaper/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-escaper/issues", - "rss": "https://github.com/laminas/laminas-escaper/releases.atom", - "source": "https://github.com/laminas/laminas-escaper" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2025-05-06T19:29:36+00:00" - }, - { - "name": "league/color-extractor", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/color-extractor.git", - "reference": "21fcac6249c5ef7d00eb83e128743ee6678fe505" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/color-extractor/zipball/21fcac6249c5ef7d00eb83e128743ee6678fe505", - "reference": "21fcac6249c5ef7d00eb83e128743ee6678fe505", - "shasum": "" - }, - "require": { - "ext-gd": "*", - "php": "^7.3 || ^8.0" - }, - "replace": { - "matthecat/colorextractor": "*" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2", - "phpunit/phpunit": "^9.5" - }, - "suggest": { - "ext-curl": "To download images from remote URLs if allow_url_fopen is disabled for security reasons" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\ColorExtractor\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mathieu Lechat", - "email": "math.lechat@gmail.com", - "homepage": "http://matthecat.com", - "role": "Developer" - } - ], - "description": "Extract colors from an image as a human would do.", - "homepage": "https://github.com/thephpleague/color-extractor", - "keywords": [ - "color", - "extract", - "human", - "image", - "palette" - ], - "support": { - "issues": "https://github.com/thephpleague/color-extractor/issues", - "source": "https://github.com/thephpleague/color-extractor/tree/0.4.0" - }, - "time": "2022-09-24T15:57:16+00:00" - }, - { - "name": "michelf/php-smartypants", - "version": "1.8.1", - "source": { - "type": "git", - "url": "https://github.com/michelf/php-smartypants.git", - "reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/michelf/php-smartypants/zipball/47d17c90a4dfd0ccf1f87e25c65e6c8012415aad", - "reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Michelf": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Michel Fortin", - "email": "michel.fortin@michelf.ca", - "homepage": "https://michelf.ca/", - "role": "Developer" - }, - { - "name": "John Gruber", - "homepage": "https://daringfireball.net/" - } - ], - "description": "PHP SmartyPants", - "homepage": "https://michelf.ca/projects/php-smartypants/", - "keywords": [ - "dashes", - "quotes", - "spaces", - "typographer", - "typography" - ], - "support": { - "issues": "https://github.com/michelf/php-smartypants/issues", - "source": "https://github.com/michelf/php-smartypants/tree/1.8.1" - }, - "time": "2016-12-13T01:01:17+00:00" - }, - { - "name": "phpmailer/phpmailer", - "version": "v6.10.0", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144", - "reference": "bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "doctrine/annotations": "^1.2.6 || ^1.13.3", - "php-parallel-lint/php-console-highlighter": "^1.0.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.7.2", - "yoast/phpunit-polyfills": "^1.0.4" - }, - "suggest": { - "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "ext-openssl": "Needed for secure SMTP sending and DKIM signing", - "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", - "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-only" - ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "support": { - "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.10.0" - }, - "funding": [ - { - "url": "https://github.com/Synchro", - "type": "github" - } - ], - "time": "2025-04-24T15:19:31+00:00" - }, - { - "name": "psr/log", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/3.0.2" - }, - "time": "2024-09-11T13:17:53+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.6.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.6-dev" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:21:43+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.32.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" - }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.32.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", - "shasum": "" - }, - "require": { - "php": ">=7.2", - "symfony/polyfill-intl-normalizer": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Trevor Rowbotham", - "email": "trevor.rowbotham@pm.me" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "idn", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.32.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-10T14:38:51+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.32.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "3833d7255cc303546435cb650316bff708a1c75c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", - "reference": "3833d7255cc303546435cb650316bff708a1c75c", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.32.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", - "shasum": "" - }, - "require": { - "ext-iconv": "*", - "php": ">=7.2" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-12-23T08:48:59+00:00" - }, - { - "name": "symfony/yaml", - "version": "v7.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "cea40a48279d58dc3efee8112634cb90141156c2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/cea40a48279d58dc3efee8112634cb90141156c2", - "reference": "cea40a48279d58dc3efee8112634cb90141156c2", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0" - }, - "bin": [ - "Resources/bin/yaml-lint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Loads and dumps YAML files", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v7.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2025-04-04T10:10:33+00:00" + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "43770e3691ceb6a19553beb3dbca1057", + "packages": [ + { + "name": "christian-riesen/base32", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://github.com/ChristianRiesen/base32.git", + "reference": "2e82dab3baa008e24a505649b0d583c31d31e894" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ChristianRiesen/base32/zipball/2e82dab3baa008e24a505649b0d583c31d31e894", + "reference": "2e82dab3baa008e24a505649b0d583c31d31e894", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.17", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^8.5.13 || ^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": {}, - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "autoload": { + "psr-4": { + "Base32\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Riesen", + "email": "chris.riesen@gmail.com", + "homepage": "http://christianriesen.com", + "role": "Developer" + } + ], + "description": "Base32 encoder/decoder according to RFC 4648", + "homepage": "https://github.com/ChristianRiesen/base32", + "keywords": [ + "base32", + "decode", + "encode", + "rfc4648" + ], + "support": { + "issues": "https://github.com/ChristianRiesen/base32/issues", + "source": "https://github.com/ChristianRiesen/base32/tree/1.6.0" + }, + "time": "2021-02-26T10:19:33+00:00" }, - "platform-dev": {}, - "plugin-api-version": "2.6.0" + { + "name": "claviska/simpleimage", + "version": "4.2.1", + "source": { + "type": "git", + "url": "https://github.com/claviska/SimpleImage.git", + "reference": "ec6d5021e5a7153a2520d64c59b86b6f3c4157c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/claviska/SimpleImage/zipball/ec6d5021e5a7153a2520d64c59b86b6f3c4157c5", + "reference": "ec6d5021e5a7153a2520d64c59b86b6f3c4157c5", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "league/color-extractor": "0.4.*", + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "^1.5", + "phpstan/phpstan": "^1.10" + }, + "type": "library", + "autoload": { + "psr-0": { + "claviska": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Cory LaViska", + "homepage": "http://www.abeautifulsite.net/", + "role": "Developer" + } + ], + "description": "A PHP class that makes working with images as simple as possible.", + "support": { + "issues": "https://github.com/claviska/SimpleImage/issues", + "source": "https://github.com/claviska/SimpleImage/tree/4.2.1" + }, + "funding": [ + { + "url": "https://github.com/claviska", + "type": "github" + } + ], + "time": "2024-11-22T13:25:03+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.3", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-09-19T14:15:21+00:00" + }, + { + "name": "filp/whoops", + "version": "2.18.3", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "59a123a3d459c5a23055802237cb317f609867e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/59a123a3d459c5a23055802237cb317f609867e5", + "reference": "59a123a3d459c5a23055802237cb317f609867e5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.18.3" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2025-06-16T00:02:10+00:00" + }, + { + "name": "getkirby/cms", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/getkirby/kirby.git", + "reference": "2ff182ba39ddea19fa1615bd3733f734b5e53842" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getkirby/kirby/zipball/2ff182ba39ddea19fa1615bd3733f734b5e53842", + "reference": "2ff182ba39ddea19fa1615bd3733f734b5e53842", + "shasum": "" + }, + "require": { + "christian-riesen/base32": "1.6.0", + "claviska/simpleimage": "4.2.1", + "composer/semver": "3.4.3", + "ext-ctype": "*", + "ext-curl": "*", + "ext-dom": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-iconv": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-simplexml": "*", + "filp/whoops": "2.18.3", + "getkirby/composer-installer": "^1.2.1", + "laminas/laminas-escaper": "2.17.0", + "michelf/php-smartypants": "1.8.1", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "phpmailer/phpmailer": "6.10.0", + "symfony/polyfill-intl-idn": "1.32.0", + "symfony/polyfill-mbstring": "1.32.0", + "symfony/yaml": "7.3.0" + }, + "replace": { + "symfony/polyfill-php72": "*" + }, + "suggest": { + "ext-PDO": "Support for using databases", + "ext-apcu": "Support for the Apcu cache driver", + "ext-exif": "Support for exif information from images", + "ext-fileinfo": "Improved mime type detection for files", + "ext-intl": "Improved i18n number formatting", + "ext-memcached": "Support for the Memcached cache driver", + "ext-redis": "Support for the Redis cache driver", + "ext-sodium": "Support for the crypto class and more robust session handling", + "ext-zip": "Support for ZIP archive file functions", + "ext-zlib": "Sanitization and validation for svgz files" + }, + "type": "kirby-cms", + "extra": { + "unused": [ + "symfony/polyfill-intl-idn" + ] + }, + "autoload": { + "files": [ + "config/setup.php", + "config/helpers.php" + ], + "psr-4": { + "Kirby\\": "src/" + }, + "classmap": [ + "dependencies/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "proprietary" + ], + "authors": [ + { + "name": "Kirby Team", + "email": "support@getkirby.com", + "homepage": "https://getkirby.com" + } + ], + "description": "The Kirby core", + "homepage": "https://getkirby.com", + "keywords": [ + "cms", + "core", + "kirby" + ], + "support": { + "email": "support@getkirby.com", + "forum": "https://forum.getkirby.com", + "issues": "https://github.com/getkirby/kirby/issues", + "source": "https://github.com/getkirby/kirby" + }, + "funding": [ + { + "url": "https://getkirby.com/buy", + "type": "custom" + } + ], + "time": "2025-06-24T07:42:42+00:00" + }, + { + "name": "getkirby/composer-installer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/getkirby/composer-installer.git", + "reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getkirby/composer-installer/zipball/c98ece30bfba45be7ce457e1102d1b169d922f3d", + "reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "require-dev": { + "composer/composer": "^1.8 || ^2.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Kirby\\ComposerInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "Kirby\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Kirby's custom Composer installer for the Kirby CMS and for Kirby plugins", + "homepage": "https://getkirby.com", + "support": { + "issues": "https://github.com/getkirby/composer-installer/issues", + "source": "https://github.com/getkirby/composer-installer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://getkirby.com/buy", + "type": "custom" + } + ], + "time": "2020-12-28T12:54:39+00:00" + }, + { + "name": "laminas/laminas-escaper", + "version": "2.17.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-escaper.git", + "reference": "df1ef9503299a8e3920079a16263b578eaf7c3ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/df1ef9503299a8e3920079a16263b578eaf7c3ba", + "reference": "df1ef9503299a8e3920079a16263b578eaf7c3ba", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-mbstring": "*", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "conflict": { + "zendframework/zend-escaper": "*" + }, + "require-dev": { + "infection/infection": "^0.29.8", + "laminas/laminas-coding-standard": "~3.0.1", + "phpunit/phpunit": "^10.5.45", + "psalm/plugin-phpunit": "^0.19.2", + "vimeo/psalm": "^6.6.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Laminas\\Escaper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", + "homepage": "https://laminas.dev", + "keywords": [ + "escaper", + "laminas" + ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-escaper/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-escaper/issues", + "rss": "https://github.com/laminas/laminas-escaper/releases.atom", + "source": "https://github.com/laminas/laminas-escaper" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2025-05-06T19:29:36+00:00" + }, + { + "name": "league/color-extractor", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/color-extractor.git", + "reference": "21fcac6249c5ef7d00eb83e128743ee6678fe505" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/color-extractor/zipball/21fcac6249c5ef7d00eb83e128743ee6678fe505", + "reference": "21fcac6249c5ef7d00eb83e128743ee6678fe505", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "php": "^7.3 || ^8.0" + }, + "replace": { + "matthecat/colorextractor": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "ext-curl": "To download images from remote URLs if allow_url_fopen is disabled for security reasons" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\ColorExtractor\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathieu Lechat", + "email": "math.lechat@gmail.com", + "homepage": "http://matthecat.com", + "role": "Developer" + } + ], + "description": "Extract colors from an image as a human would do.", + "homepage": "https://github.com/thephpleague/color-extractor", + "keywords": [ + "color", + "extract", + "human", + "image", + "palette" + ], + "support": { + "issues": "https://github.com/thephpleague/color-extractor/issues", + "source": "https://github.com/thephpleague/color-extractor/tree/0.4.0" + }, + "time": "2022-09-24T15:57:16+00:00" + }, + { + "name": "michelf/php-smartypants", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/michelf/php-smartypants.git", + "reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/michelf/php-smartypants/zipball/47d17c90a4dfd0ccf1f87e25c65e6c8012415aad", + "reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Michelf": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" + } + ], + "description": "PHP SmartyPants", + "homepage": "https://michelf.ca/projects/php-smartypants/", + "keywords": [ + "dashes", + "quotes", + "spaces", + "typographer", + "typography" + ], + "support": { + "issues": "https://github.com/michelf/php-smartypants/issues", + "source": "https://github.com/michelf/php-smartypants/tree/1.8.1" + }, + "time": "2016-12-13T01:01:17+00:00" + }, + { + "name": "phpmailer/phpmailer", + "version": "v6.10.0", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144", + "reference": "bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "doctrine/annotations": "^1.2.6 || ^1.13.3", + "php-parallel-lint/php-console-highlighter": "^1.0.0", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.7.2", + "yoast/phpunit-polyfills": "^1.0.4" + }, + "suggest": { + "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", + "ext-openssl": "Needed for secure SMTP sending and DKIM signing", + "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", + "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.10.0" + }, + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "time": "2025-04-24T15:19:31+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-10T14:38:51+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "cea40a48279d58dc3efee8112634cb90141156c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/cea40a48279d58dc3efee8112634cb90141156c2", + "reference": "cea40a48279d58dc3efee8112634cb90141156c2", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-04-04T10:10:33+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/index.php b/index.php index f9905dd..44c0ca3 100644 --- a/index.php +++ b/index.php @@ -1,9 +1,9 @@ [ - 'index' => __DIR__ - ] -]))->render(); \ No newline at end of file + echo (new Kirby([ + 'roots' => [ + 'index' => __DIR__, + ], + ]))->render(); \ No newline at end of file diff --git a/package.json b/package.json index 94cc3be..e0df7e7 100644 --- a/package.json +++ b/package.json @@ -2,14 +2,12 @@ "name": "kirby-composer", "version": "1.0.0", "description": "Kirby Composer Template", - "dependencies": { "@tailwindcss/cli": "^4.1.10", "tailwindcss": "^4.1.10" }, - "scripts": { "watch": "npx @tailwindcss/cli -i ./src/css/input.css -o ./assets/css/styles.css --content './site/**/*.php' --watch", "build": "npx @tailwindcss/cli -i ./src/css/input.css -o ./assets/css/styles.css --content './site/**/*.php'" -} + } } \ No newline at end of file diff --git a/site/snippets/footer.php b/site/snippets/footer.php index d6a6ad7..3da92e9 100644 --- a/site/snippets/footer.php +++ b/site/snippets/footer.php @@ -10,74 +10,132 @@ */ ?> -
-
- - diff --git a/site/snippets/hero.php b/site/snippets/hero.php index 87de34a..0f65d82 100644 --- a/site/snippets/hero.php +++ b/site/snippets/hero.php @@ -17,7 +17,8 @@

title() ?>

- Ihr Text kommt hier. Lorem ipsum dolor sit amet, consectetur + Ihr Text kommt hier. Lorem ipsum dolor sit amet, + consectetur adipiscing elit.

diff --git a/site/snippets/navbar.php b/site/snippets/navbar.php index 49f3cdf..940411a 100644 --- a/site/snippets/navbar.php +++ b/site/snippets/navbar.php @@ -1,166 +1,274 @@ - \ No newline at end of file diff --git a/site/templates/default.php b/site/templates/default.php index d963ec7..3cfbfec 100644 --- a/site/templates/default.php +++ b/site/templates/default.php @@ -24,8 +24,6 @@ - - diff --git a/src/css/input.css b/src/css/input.css index 4491a0a..4ae1d8c 100644 --- a/src/css/input.css +++ b/src/css/input.css @@ -1,41 +1,41 @@ @import "tailwindcss"; @theme { - --font-sans: 'Ubuntu', sans-serif; - --font-serif: 'Roboto', sans-serif; - --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', - monospace; - --color-sf_blau-50: #ebeef4; - --color-sf_blau-100: #c7cee4; - --color-sf_blau-200: #a3afd4; - --color-sf_blau-300: #7e91c5; - --color-sf_blau-400: #5574b5; - --color-sf_blau-500: #1d59a5; - --color-sf_blau-600: #1b5197; - --color-sf_blau-700: #184a89; - --color-sf_blau-800: #16437c; - --color-sf_blau-900: #143c6f; - --color-sf_blau-950: #113562; - --color-sf_gelb-50: #fdf4ec; - --color-sf_gelb-100: #fee5c9; - --color-sf_gelb-200: #fed6a6; - --color-sf_gelb-300: #fbc883; - --color-sf_gelb-400: #f6b95f; - --color-sf_gelb-500: #f0ab38; - --color-sf_gelb-600: #dc9d33; - --color-sf_gelb-700: #c88e2f; - --color-sf_gelb-800: #b4802a; - --color-sf_gelb-900: #a17326; - --color-sf_gelb-950: #8e6521; - --color-sf_grau-50: #ededed; - --color-sf_grau-100: #cdcdcd; - --color-sf_grau-200: #adadad; - --color-sf_grau-300: #8f8f8f; - --color-sf_grau-400: #717171; - --color-sf_grau-500: #555555; - --color-sf_grau-600: #4e4e4e; - --color-sf_grau-700: #474747; - --color-sf_grau-800: #404040; - --color-sf_grau-900: #393939; - --color-sf_grau-950: #323232; + --font-sans: 'Ubuntu', sans-serif; + --font-serif: 'Roboto', sans-serif; + --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', + monospace; + --color-sf_blau-50: #ebeef4; + --color-sf_blau-100: #c7cee4; + --color-sf_blau-200: #a3afd4; + --color-sf_blau-300: #7e91c5; + --color-sf_blau-400: #5574b5; + --color-sf_blau-500: #1d59a5; + --color-sf_blau-600: #1b5197; + --color-sf_blau-700: #184a89; + --color-sf_blau-800: #16437c; + --color-sf_blau-900: #143c6f; + --color-sf_blau-950: #113562; + --color-sf_gelb-50: #fdf4ec; + --color-sf_gelb-100: #fee5c9; + --color-sf_gelb-200: #fed6a6; + --color-sf_gelb-300: #fbc883; + --color-sf_gelb-400: #f6b95f; + --color-sf_gelb-500: #f0ab38; + --color-sf_gelb-600: #dc9d33; + --color-sf_gelb-700: #c88e2f; + --color-sf_gelb-800: #b4802a; + --color-sf_gelb-900: #a17326; + --color-sf_gelb-950: #8e6521; + --color-sf_grau-50: #ededed; + --color-sf_grau-100: #cdcdcd; + --color-sf_grau-200: #adadad; + --color-sf_grau-300: #8f8f8f; + --color-sf_grau-400: #717171; + --color-sf_grau-500: #555555; + --color-sf_grau-600: #4e4e4e; + --color-sf_grau-700: #474747; + --color-sf_grau-800: #404040; + --color-sf_grau-900: #393939; + --color-sf_grau-950: #323232; } \ No newline at end of file