() => {
  it('invokes with the component context', async () => {
    expect.assertions(2)
    const spy = jest
      .fn()
      .mockImplementationOnce(function (this: any, to, from, next) {
        expect(typeof this.counter).toBe('number')
        next()
      })
    const WithLeave = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: spy,
    })

    const router = createRouter({
      history: createMemoryHistory(),
      routes: [
        { path: '/', component },
        { path: '/leave', component: WithLeave as any },
      ],
    })
    const app = createApp({
      template: `
      <router-view />
      `,
    })
    app.use(router)
    const rootEl = document.createElement('div')
    document.body.appendChild(rootEl)
    app.mount(rootEl)

    await router.isReady()
    await router.push('/leave')
    await router.push('/')
    expect(spy).toHaveBeenCalledTimes(1)
  })

  it('invokes with the component context with named views', async () => {
    expect.assertions(2)
    const WithLeaveOne = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })
    const WithLeaveTwo = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })

    const router = createRouter({
      history: createMemoryHistory(),
      routes: [
        { path: '/', component },
        {
          path: '/leave',
          components: {
            one: WithLeaveOne as any,
            two: WithLeaveTwo as any,
          },
        },
      ],
    })
    const app = createApp({
      template: `
      <router-view name="one" />
      <router-view name="two" />
      `,
    })
    app.use(router)
    const rootEl = document.createElement('div')
    document.body.appendChild(rootEl)
    app.mount(rootEl)

    await router.isReady()
    await router.push('/leave')
    await router.push('/')
  })

  it('invokes with the component context with nested views', async () => {
    expect.assertions(2)
    const WithLeaveParent = defineComponent({
      template: `<router-view/>`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })
    const WithLeave = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })

    const router = createRouter({
      history: createMemoryHistory(),
      routes: [
        { path: '/', component },
        {
          path: '/leave',
          component: WithLeaveParent as any,
          children: [
            {
              path: '',
              component: WithLeave as any,
            },
          ],
        },
      ],
    })
    const app = createApp({
      template: `
      <router-view />
      `,
    })
    app.use(router)
    const rootEl = document.createElement('div')
    document.body.appendChild(rootEl)
    app.mount(rootEl)

    await router.isReady()
    await router.push('/leave')
    await router.push('/')
  })

  it('invokes with the component context with nested named views', async () => {
    expect.assertions(3)
    const WithLeaveParent = defineComponent({
      template: `
      <router-view name="one"/>
      <router-view name="two"/>
      `,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })
    const WithLeaveOne = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })
    const WithLeaveTwo = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })

    const router = createRouter({
      history: createMemoryHistory(),
      routes: [
        { path: '/', component },
        {
          path: '/leave',
          component: WithLeaveParent as any,
          children: [
            {
              path: '',
              components: {
                one: WithLeaveOne as any,
                two: WithLeaveTwo as any,
              },
            },
          ],
        },
      ],
    })
    const app = createApp({
      template: `
      <router-view />
      `,
    })
    app.use(router)
    const rootEl = document.createElement('div')
    document.body.appendChild(rootEl)
    app.mount(rootEl)

    await router.isReady()
    await router.push('/leave')
    await router.push('/')
  })
}


async () => {
    expect.assertions(2)
    const spy = jest
      .fn()
      .mockImplementationOnce(function (this: any, to, from, next) {
        expect(typeof this.counter).toBe('number')
        next()
      })
    const WithLeave = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: spy,
    })

    const router = createRouter({
      history: createMemoryHistory(),
      routes: [
        { path: '/', component },
        { path: '/leave', component: WithLeave as any },
      ],
    })
    const app = createApp({
      template: `
      <router-view />
      `,
    })
    app.use(router)
    const rootEl = document.createElement('div')
    document.body.appendChild(rootEl)
    app.mount(rootEl)

    await router.isReady()
    await router.push('/leave')
    await router.push('/')
    expect(spy).toHaveBeenCalledTimes(1)
  }


() => ({ counter: 0 })


async () => {
    expect.assertions(2)
    const WithLeaveOne = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })
    const WithLeaveTwo = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })

    const router = createRouter({
      history: createMemoryHistory(),
      routes: [
        { path: '/', component },
        {
          path: '/leave',
          components: {
            one: WithLeaveOne as any,
            two: WithLeaveTwo as any,
          },
        },
      ],
    })
    const app = createApp({
      template: `
      <router-view name="one" />
      <router-view name="two" />
      `,
    })
    app.use(router)
    const rootEl = document.createElement('div')
    document.body.appendChild(rootEl)
    app.mount(rootEl)

    await router.isReady()
    await router.push('/leave')
    await router.push('/')
  }


async () => {
    expect.assertions(2)
    const WithLeaveParent = defineComponent({
      template: `<router-view/>`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })
    const WithLeave = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })

    const router = createRouter({
      history: createMemoryHistory(),
      routes: [
        { path: '/', component },
        {
          path: '/leave',
          component: WithLeaveParent as any,
          children: [
            {
              path: '',
              component: WithLeave as any,
            },
          ],
        },
      ],
    })
    const app = createApp({
      template: `
      <router-view />
      `,
    })
    app.use(router)
    const rootEl = document.createElement('div')
    document.body.appendChild(rootEl)
    app.mount(rootEl)

    await router.isReady()
    await router.push('/leave')
    await router.push('/')
  }


async () => {
    expect.assertions(3)
    const WithLeaveParent = defineComponent({
      template: `
      <router-view name="one"/>
      <router-view name="two"/>
      `,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })
    const WithLeaveOne = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })
    const WithLeaveTwo = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteLeave: jest
        .fn()
        .mockImplementationOnce(function (this: any, to, from, next) {
          expect(typeof this.counter).toBe('number')
          next()
        }),
    })

    const router = createRouter({
      history: createMemoryHistory(),
      routes: [
        { path: '/', component },
        {
          path: '/leave',
          component: WithLeaveParent as any,
          children: [
            {
              path: '',
              components: {
                one: WithLeaveOne as any,
                two: WithLeaveTwo as any,
              },
            },
          ],
        },
      ],
    })
    const app = createApp({
      template: `
      <router-view />
      `,
    })
    app.use(router)
    const rootEl = document.createElement('div')
    document.body.appendChild(rootEl)
    app.mount(rootEl)

    await router.isReady()
    await router.push('/leave')
    await router.push('/')
  }


() => {
  it('invokes with the component context', async () => {
    expect.assertions(2)
    const spy = jest
      .fn()
      .mockImplementationOnce(function (this: any, to, from, next) {
        expect(typeof this.counter).toBe('number')
        next()
      })
    const WithParam = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteUpdate: spy,
    })

    const router = createRouter({
      history: createMemoryHistory(),
      routes: [
        { path: '/', component },
        { path: '/:id', component: WithParam },
      ],
    })
    const app = createApp({
      template: `
      <router-view />
      `,
    })
    app.use(router)
    const rootEl = document.createElement('div')
    document.body.appendChild(rootEl)
    app.mount(rootEl)

    await router.isReady()
    await router.push('/one')
    await router.push('/foo')
    expect(spy).toHaveBeenCalledTimes(1)
  })
}


async () => {
    expect.assertions(2)
    const spy = jest
      .fn()
      .mockImplementationOnce(function (this: any, to, from, next) {
        expect(typeof this.counter).toBe('number')
        next()
      })
    const WithParam = defineComponent({
      template: `text`,
      // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
      data: () => ({ counter: 0 }),
      beforeRouteUpdate: spy,
    })

    const router = createRouter({
      history: createMemoryHistory(),
      routes: [
        { path: '/', component },
        { path: '/:id', component: WithParam },
      ],
    })
    const app = createApp({
      template: `
      <router-view />
      `,
    })
    app.use(router)
    const rootEl = document.createElement('div')
    document.body.appendChild(rootEl)
    app.mount(rootEl)

    await router.isReady()
    await router.push('/one')
    await router.push('/foo')
    expect(spy).toHaveBeenCalledTimes(1)
  }


() => {
		it('should instantiate when no args are given', () => {
			expect(new Log()).toBeInstanceOf(Log);
		});

		it(`should class 'activateDefaultConsole' if 'consoleEnabled' is true`, () => {
			const spy = jest.spyOn(Log.prototype, 'activateDefaultConsole');
			expect(spy).not.toHaveBeenCalled();

			new Log({id: 'consoleEnabled', consoleEnabled: true});

			expect(spy).toHaveBeenCalled();
		});

		it(`should throw when 'state' is not a LogStateGlobal`, () => {
			expect(() => {
				new Log({state: {} as any});
			}).toThrow(`Bad Log init - 'state' was not an instance of LogStateGlobal.`);
		});
	}


() => {
			expect(new Log()).toBeInstanceOf(Log);
		}


() => {
			const spy = jest.spyOn(Log.prototype, 'activateDefaultConsole');
			expect(spy).not.toHaveBeenCalled();

			new Log({id: 'consoleEnabled', consoleEnabled: true});

			expect(spy).toHaveBeenCalled();
		}


() => {
			expect(() => {
				new Log({state: {} as any});
			}).toThrow(`Bad Log init - 'state' was not an instance of LogStateGlobal.`);
		}


() => {
				new Log({state: {} as any});
			}


() => {
			describe(`activateDefaultConsole`, () => {
				it(`should create a transport with level arg`, () => {
					const level = 13;
					expect(level).not.toBe(log.globalState.globalLevel.get());
					expect(log.groupState.transports.size).toBe(0);

					log.activateDefaultConsole(level);

					expect(log.groupState.transports.size).toBe(1);
					expect(log.groupState.transports.values().next().value.level.get()).toBe(level);
					log.reset();
				});
			});

			describe(`deactiveDefaultConsole`, () => {
				it(`should remove transport with id 'console' from log`, () => {
					log.activateDefaultConsole();

					expect(log.getTransport('console')).not.toBeNull();

					log.deactivateDefaultConsole();

					expect(log.getTransport('console')).toBeNull();

					log.groupState.transports.clear();
				});
			});

			describe(`setLevelDefaultConsole`, () => {
				it(`should set the level of 'console'`, () => {
					const startingLevel = 5;
					const changedLevel = startingLevel * 2;

					log.activateDefaultConsole(startingLevel);

					log.setLevelDefaultConsole(changedLevel);

					const transport = log.getTransport('console');
					const result = transport?.level.get();

					expect(result).toBe(changedLevel);

					log.groupState.transports.clear();
				});
			});

			describe(`enableLevelDefaultConsole`, () => {
				it(`should add the level to 'console'`, () => {
					const startingLevel = 0b10101;
					const addedLevel = 0b00010;
					const totalLevel = startingLevel | addedLevel;

					log.activateDefaultConsole(startingLevel);

					log.enableLevelDefaultConsole(addedLevel);

					const transport = log.getTransport('console')!;
					const result = transport.level.get();

					expect(result).toBe(totalLevel);
					log.groupState.transports.clear();
				});
			});

			describe(`disableLevelDefaultConsole`, () => {
				it(`should remove the level from 'console'`, () => {
					const startingLevel = 0b10101;
					const removedLevel = 0b00100;
					const totalLevel = startingLevel ^ removedLevel;

					log.activateDefaultConsole(startingLevel);

					log.disableLevelDefaultConsole(removedLevel);

					const transport = log.getTransport('console')!;
					const result = transport.level.get();

					expect(result).toBe(totalLevel);
					log.groupState.transports.clear();
				});
			});
		}


() => {
				it(`should create a transport with level arg`, () => {
					const level = 13;
					expect(level).not.toBe(log.globalState.globalLevel.get());
					expect(log.groupState.transports.size).toBe(0);

					log.activateDefaultConsole(level);

					expect(log.groupState.transports.size).toBe(1);
					expect(log.groupState.transports.values().next().value.level.get()).toBe(level);
					log.reset();
				});
			}


() => {
					const level = 13;
					expect(level).not.toBe(log.globalState.globalLevel.get());
					expect(log.groupState.transports.size).toBe(0);

					log.activateDefaultConsole(level);

					expect(log.groupState.transports.size).toBe(1);
					expect(log.groupState.transports.values().next().value.level.get()).toBe(level);
					log.reset();
				}


() => {
				it(`should remove transport with id 'console' from log`, () => {
					log.activateDefaultConsole();

					expect(log.getTransport('console')).not.toBeNull();

					log.deactivateDefaultConsole();

					expect(log.getTransport('console')).toBeNull();

					log.groupState.transports.clear();
				});
			}


() => {
					log.activateDefaultConsole();

					expect(log.getTransport('console')).not.toBeNull();

					log.deactivateDefaultConsole();

					expect(log.getTransport('console')).toBeNull();

					log.groupState.transports.clear();
				}


() => {
				it(`should set the level of 'console'`, () => {
					const startingLevel = 5;
					const changedLevel = startingLevel * 2;

					log.activateDefaultConsole(startingLevel);

					log.setLevelDefaultConsole(changedLevel);

					const transport = log.getTransport('console');
					const result = transport?.level.get();

					expect(result).toBe(changedLevel);

					log.groupState.transports.clear();
				});
			}


() => {
					const startingLevel = 5;
					const changedLevel = startingLevel * 2;

					log.activateDefaultConsole(startingLevel);

					log.setLevelDefaultConsole(changedLevel);

					const transport = log.getTransport('console');
					const result = transport?.level.get();

					expect(result).toBe(changedLevel);

					log.groupState.transports.clear();
				}


() => {
				it(`should add the level to 'console'`, () => {
					const startingLevel = 0b10101;
					const addedLevel = 0b00010;
					const totalLevel = startingLevel | addedLevel;

					log.activateDefaultConsole(startingLevel);

					log.enableLevelDefaultConsole(addedLevel);

					const transport = log.getTransport('console')!;
					const result = transport.level.get();

					expect(result).toBe(totalLevel);
					log.groupState.transports.clear();
				});
			}


() => {
					const startingLevel = 0b10101;
					const addedLevel = 0b00010;
					const totalLevel = startingLevel | addedLevel;

					log.activateDefaultConsole(startingLevel);

					log.enableLevelDefaultConsole(addedLevel);

					const transport = log.getTransport('console')!;
					const result = transport.level.get();

					expect(result).toBe(totalLevel);
					log.groupState.transports.clear();
				}


() => {
				it(`should remove the level from 'console'`, () => {
					const startingLevel = 0b10101;
					const removedLevel = 0b00100;
					const totalLevel = startingLevel ^ removedLevel;

					log.activateDefaultConsole(startingLevel);

					log.disableLevelDefaultConsole(removedLevel);

					const transport = log.getTransport('console')!;
					const result = transport.level.get();

					expect(result).toBe(totalLevel);
					log.groupState.transports.clear();
				});
			}


() => {
					const startingLevel = 0b10101;
					const removedLevel = 0b00100;
					const totalLevel = startingLevel ^ removedLevel;

					log.activateDefaultConsole(startingLevel);

					log.disableLevelDefaultConsole(removedLevel);

					const transport = log.getTransport('console')!;
					const result = transport.level.get();

					expect(result).toBe(totalLevel);
					log.groupState.transports.clear();
				}


() => {
			it('should return null when id arg is an empty string', () => {
				expect(log.makeLog(EMPTY_STRING, {level: Levels.DEBUG})).toBeNull();
			});

			it('should return group when id already exists', () => {
				const id = '194714_8841978AF';
				const expected = log.makeLog(id, {level: Levels.DEBUG});

				const result = log.makeLog(id);

				expect(result).toBe(expected);
			});

			it('should return group when id is created', () => {
				const id = '491719714';
				expect(log.globalState.groups[id]).toBeUndefined();

				const result = log.makeLog(id, {level: Levels.DEBUG, enabled: false});

				expect(result).toBeInstanceOf(Log);

				const groupId = result.groupState.id;
				expect(log.globalState.groups.get(groupId)).toHaveProperty('groupState');
			});
		}


() => {
				expect(log.makeLog(EMPTY_STRING, {level: Levels.DEBUG})).toBeNull();
			}


() => {
				const id = '194714_8841978AF';
				const expected = log.makeLog(id, {level: Levels.DEBUG});

				const result = log.makeLog(id);

				expect(result).toBe(expected);
			}


() => {
				const id = '491719714';
				expect(log.globalState.groups[id]).toBeUndefined();

				const result = log.makeLog(id, {level: Levels.DEBUG, enabled: false});

				expect(result).toBeInstanceOf(Log);

				const groupId = result.groupState.id;
				expect(log.globalState.groups.get(groupId)).toHaveProperty('groupState');
			}


() => {
			describe('addTransport', () => {
				it('should not add the same transport more than once', () => {
					log.addTransport(TRANSPORT);

					for (let i = 0; i < 5; i++) {
						expect(log.addTransport(TRANSPORT)).toBe(false);
					}

					log.clear();
				});

				it('should return false and should not add a transport when transport arg is undefined', () => {
					expect(log.groupState.transports.size).toBe(0);

					expect(log.addTransport(undefined as any)).toBe(false);

					expect(log.groupState.transports.size).toBe(0);
				});

				it('should return false and should not add a transport when transport arg is null', () => {
					expect(log.groupState.transports.size).toBe(0);

					expect(log.addTransport(null as any)).toBe(false);

					expect(log.groupState.transports.size).toBe(0);
				});

				it(`should add transport to group`, () => {
					const transport = new Transport('11097141', Levels.ALL, ACTION);
					expect(log.groupState.transports.size).toBe(0);

					log.addTransport(transport);

					expect(log.groupState.transports.size).toBe(1);
					log.clear();
				});
			});

			describe(`getTransport`, () => {
				it(`should return transport if one matching transportId exists`, () => {
					log.addTransport(TRANSPORT);

					const result = log.getTransport(TRANSPORT.id);

					expect(result).toBe(TRANSPORT);

					log.groupState.transports.clear();
				});

				it(`should return null if no matching transport exists`, () => {
					expect(log.groupState.transports.has(TRANSPORT)).toBe(false);

					const result = log.getTransport(TRANSPORT.id);

					expect(result).toBeNull();
				});
			});

			describe('removeTransport', () => {
				it('should return false when transport does not exist in group', () => {
					expect(log.removeTransport(TRANSPORT)).toBe(false);
				});

				it('should return false when transport arg is undefined', () => {
					expect(log.removeTransport(undefined as any)).toBe(false);
				});

				it('should remove transport group', () => {
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(1);
					log.removeTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(0);
				});

				it('should return true when transport is removed', () => {
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(1);
					const result = log.removeTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(0);
					expect(result).toBe(true);
				});
			});

			describe('removeTransportById', () => {
				it('should remove transport from group', () => {
					const transport = new Transport('id', Levels.ALL, ACTION);
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(transport);
					expect(log.groupState.transports.size).toBe(1);
					const result = log.removeTransportById('id');
					expect(log.groupState.transports.size).toBe(0);
					expect(result).toBeTruthy();
				});

				it('should return false if no transports are removed', () => {
					const transport = new Transport('id', Levels.ALL, ACTION);
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(transport);
					expect(log.groupState.transports.size).toBe(1);
					const result = log.removeTransportById('id2');
					expect(log.groupState.transports.size).toBe(1);
					expect(result).toBeFalsy();
				});
			});

			describe('removeTransports', () => {
				it('should return false when transports is not an array', () => {
					const result = log.removeTransports(null as any);

					expect(result).toBe(false);
				});

				it('should return false when no transports are removed', () => {
					const result = log.removeTransports([TRANSPORT]);

					expect(result).toBe(false);
				});

				it('should return true when a transport is removed', () => {
					log.clear();
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(1);

					const result = log.removeTransports([TRANSPORT]);

					expect(result).toBe(true);
					expect(log.groupState.transports.size).toBe(0);
				});
			});

			describe('removeTransportEverywhere', () => {
				it('should return false when transport is undefined', () => {
					expect(log.removeTransportEverywhere(undefined as any)).toBe(false);
				});

				it('should return false when transport is null', () => {
					expect(log.removeTransportEverywhere(null as any)).toBe(false);
				});

				it('should return false when transport arg is provided but is not a Transport', () => {
					expect(log.removeTransportEverywhere(141971 as any)).toBe(false);
				});

				it('should remove transport from all groups', () => {
					const group1 = log.makeLog('14971497_7d7AKHF');
					const group2 = log.makeLog('149719971_f7f7AA');
					const group3 = log.makeLog('778910891_KHF8M4');

					group1.addTransport(TRANSPORT);
					group2.addTransport(TRANSPORT);
					group3.addTransport(TRANSPORT);

					expect(group1.groupState.transports.size).toBe(1);
					expect(group2.groupState.transports.size).toBe(1);
					expect(group3.groupState.transports.size).toBe(1);

					log.removeTransportEverywhere(TRANSPORT);

					expect(group1.groupState.transports.size).toBe(0);
					expect(group2.groupState.transports.size).toBe(0);
					expect(group3.groupState.transports.size).toBe(0);
				});
			});
		}


() => {
				it('should not add the same transport more than once', () => {
					log.addTransport(TRANSPORT);

					for (let i = 0; i < 5; i++) {
						expect(log.addTransport(TRANSPORT)).toBe(false);
					}

					log.clear();
				});

				it('should return false and should not add a transport when transport arg is undefined', () => {
					expect(log.groupState.transports.size).toBe(0);

					expect(log.addTransport(undefined as any)).toBe(false);

					expect(log.groupState.transports.size).toBe(0);
				});

				it('should return false and should not add a transport when transport arg is null', () => {
					expect(log.groupState.transports.size).toBe(0);

					expect(log.addTransport(null as any)).toBe(false);

					expect(log.groupState.transports.size).toBe(0);
				});

				it(`should add transport to group`, () => {
					const transport = new Transport('11097141', Levels.ALL, ACTION);
					expect(log.groupState.transports.size).toBe(0);

					log.addTransport(transport);

					expect(log.groupState.transports.size).toBe(1);
					log.clear();
				});
			}


() => {
					log.addTransport(TRANSPORT);

					for (let i = 0; i < 5; i++) {
						expect(log.addTransport(TRANSPORT)).toBe(false);
					}

					log.clear();
				}


() => {
					expect(log.groupState.transports.size).toBe(0);

					expect(log.addTransport(undefined as any)).toBe(false);

					expect(log.groupState.transports.size).toBe(0);
				}


() => {
					expect(log.groupState.transports.size).toBe(0);

					expect(log.addTransport(null as any)).toBe(false);

					expect(log.groupState.transports.size).toBe(0);
				}


() => {
					const transport = new Transport('11097141', Levels.ALL, ACTION);
					expect(log.groupState.transports.size).toBe(0);

					log.addTransport(transport);

					expect(log.groupState.transports.size).toBe(1);
					log.clear();
				}


() => {
				it(`should return transport if one matching transportId exists`, () => {
					log.addTransport(TRANSPORT);

					const result = log.getTransport(TRANSPORT.id);

					expect(result).toBe(TRANSPORT);

					log.groupState.transports.clear();
				});

				it(`should return null if no matching transport exists`, () => {
					expect(log.groupState.transports.has(TRANSPORT)).toBe(false);

					const result = log.getTransport(TRANSPORT.id);

					expect(result).toBeNull();
				});
			}


() => {
					log.addTransport(TRANSPORT);

					const result = log.getTransport(TRANSPORT.id);

					expect(result).toBe(TRANSPORT);

					log.groupState.transports.clear();
				}


() => {
					expect(log.groupState.transports.has(TRANSPORT)).toBe(false);

					const result = log.getTransport(TRANSPORT.id);

					expect(result).toBeNull();
				}


() => {
				it('should return false when transport does not exist in group', () => {
					expect(log.removeTransport(TRANSPORT)).toBe(false);
				});

				it('should return false when transport arg is undefined', () => {
					expect(log.removeTransport(undefined as any)).toBe(false);
				});

				it('should remove transport group', () => {
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(1);
					log.removeTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(0);
				});

				it('should return true when transport is removed', () => {
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(1);
					const result = log.removeTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(0);
					expect(result).toBe(true);
				});
			}


() => {
					expect(log.removeTransport(TRANSPORT)).toBe(false);
				}


() => {
					expect(log.removeTransport(undefined as any)).toBe(false);
				}


() => {
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(1);
					log.removeTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(0);
				}


() => {
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(1);
					const result = log.removeTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(0);
					expect(result).toBe(true);
				}


() => {
				it('should remove transport from group', () => {
					const transport = new Transport('id', Levels.ALL, ACTION);
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(transport);
					expect(log.groupState.transports.size).toBe(1);
					const result = log.removeTransportById('id');
					expect(log.groupState.transports.size).toBe(0);
					expect(result).toBeTruthy();
				});

				it('should return false if no transports are removed', () => {
					const transport = new Transport('id', Levels.ALL, ACTION);
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(transport);
					expect(log.groupState.transports.size).toBe(1);
					const result = log.removeTransportById('id2');
					expect(log.groupState.transports.size).toBe(1);
					expect(result).toBeFalsy();
				});
			}


() => {
					const transport = new Transport('id', Levels.ALL, ACTION);
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(transport);
					expect(log.groupState.transports.size).toBe(1);
					const result = log.removeTransportById('id');
					expect(log.groupState.transports.size).toBe(0);
					expect(result).toBeTruthy();
				}


() => {
					const transport = new Transport('id', Levels.ALL, ACTION);
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(transport);
					expect(log.groupState.transports.size).toBe(1);
					const result = log.removeTransportById('id2');
					expect(log.groupState.transports.size).toBe(1);
					expect(result).toBeFalsy();
				}


() => {
				it('should return false when transports is not an array', () => {
					const result = log.removeTransports(null as any);

					expect(result).toBe(false);
				});

				it('should return false when no transports are removed', () => {
					const result = log.removeTransports([TRANSPORT]);

					expect(result).toBe(false);
				});

				it('should return true when a transport is removed', () => {
					log.clear();
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(1);

					const result = log.removeTransports([TRANSPORT]);

					expect(result).toBe(true);
					expect(log.groupState.transports.size).toBe(0);
				});
			}


() => {
					const result = log.removeTransports(null as any);

					expect(result).toBe(false);
				}


() => {
					const result = log.removeTransports([TRANSPORT]);

					expect(result).toBe(false);
				}


() => {
					log.clear();
					expect(log.groupState.transports.size).toBe(0);
					log.addTransport(TRANSPORT);
					expect(log.groupState.transports.size).toBe(1);

					const result = log.removeTransports([TRANSPORT]);

					expect(result).toBe(true);
					expect(log.groupState.transports.size).toBe(0);
				}


() => {
				it('should return false when transport is undefined', () => {
					expect(log.removeTransportEverywhere(undefined as any)).toBe(false);
				});

				it('should return false when transport is null', () => {
					expect(log.removeTransportEverywhere(null as any)).toBe(false);
				});

				it('should return false when transport arg is provided but is not a Transport', () => {
					expect(log.removeTransportEverywhere(141971 as any)).toBe(false);
				});

				it('should remove transport from all groups', () => {
					const group1 = log.makeLog('14971497_7d7AKHF');
					const group2 = log.makeLog('149719971_f7f7AA');
					const group3 = log.makeLog('778910891_KHF8M4');

					group1.addTransport(TRANSPORT);
					group2.addTransport(TRANSPORT);
					group3.addTransport(TRANSPORT);

					expect(group1.groupState.transports.size).toBe(1);
					expect(group2.groupState.transports.size).toBe(1);
					expect(group3.groupState.transports.size).toBe(1);

					log.removeTransportEverywhere(TRANSPORT);

					expect(group1.groupState.transports.size).toBe(0);
					expect(group2.groupState.transports.size).toBe(0);
					expect(group3.groupState.transports.size).toBe(0);
				});
			}


() => {
					expect(log.removeTransportEverywhere(undefined as any)).toBe(false);
				}


() => {
					expect(log.removeTransportEverywhere(null as any)).toBe(false);
				}


() => {
					expect(log.removeTransportEverywhere(141971 as any)).toBe(false);
				}


() => {
					const group1 = log.makeLog('14971497_7d7AKHF');
					const group2 = log.makeLog('149719971_f7f7AA');
					const group3 = log.makeLog('778910891_KHF8M4');

					group1.addTransport(TRANSPORT);
					group2.addTransport(TRANSPORT);
					group3.addTransport(TRANSPORT);

					expect(group1.groupState.transports.size).toBe(1);
					expect(group2.groupState.transports.size).toBe(1);
					expect(group3.groupState.transports.size).toBe(1);

					log.removeTransportEverywhere(TRANSPORT);

					expect(group1.groupState.transports.size).toBe(0);
					expect(group2.groupState.transports.size).toBe(0);
					expect(group3.groupState.transports.size).toBe(0);
				}


() => {
			describe('setGlobalLevel', () => {
				it('should not change level when level arg is undefined', () => {
					const expected = log.globalState.globalLevel.get();

					log.setGlobalLevel('adfjakha' as any);

					expect(log.globalState.globalLevel.get()).toBe(expected);
				});

				it('should set global level to 0 when level arg is NONE', () => {
					expect(log.globalState.globalLevel.get()).not.toBe(Levels.NONE);

					log.setGlobalLevel(Levels.NONE);

					expect(log.globalState.globalLevel.get()).toBe(0);
				});

				for (const level of LOG_LEVELS) {
					it(`should set level to ${level}`, () => {
						expect(log.globalState.globalLevel.get()).not.toBe(level);
						log.setGlobalLevel(level);
						expect(log.globalState.globalLevel.get()).toBe(level);
					});
				}
			});

			it(`should call enableLogLevel`, () => {
				const spy = jest.spyOn(log.globalState.globalLevel, 'enableLevel');
				expect(spy).not.toBeCalled();

				log.enableGlobalLevel(1);

				expect(spy).toBeCalled();
			});

			it(`should call enableMultipleLevels`, () => {
				const spy = jest.spyOn(log.globalState.globalLevel, 'enableLevels');
				expect(spy).not.toBeCalled();

				log.enableGlobalLevels([1]);

				expect(spy).toBeCalled();
			});

			it(`should call disableLogLevel`, () => {
				const spy = jest.spyOn(log.globalState.globalLevel, 'disableLevel');
				expect(spy).not.toBeCalled();

				log.disableGlobalLevel(1);

				expect(spy).toBeCalled();
			});

			it(`should call disableMultipleLevels`, () => {
				const spy = jest.spyOn(log.globalState.globalLevel, 'disableLevels');
				expect(spy).not.toBeCalled();

				log.disableGlobalLevels([1]);

				expect(spy).toBeCalled();
			});
		}


() => {
				it('should not change level when level arg is undefined', () => {
					const expected = log.globalState.globalLevel.get();

					log.setGlobalLevel('adfjakha' as any);

					expect(log.globalState.globalLevel.get()).toBe(expected);
				});

				it('should set global level to 0 when level arg is NONE', () => {
					expect(log.globalState.globalLevel.get()).not.toBe(Levels.NONE);

					log.setGlobalLevel(Levels.NONE);

					expect(log.globalState.globalLevel.get()).toBe(0);
				});

				for (const level of LOG_LEVELS) {
					it(`should set level to ${level}`, () => {
						expect(log.globalState.globalLevel.get()).not.toBe(level);
						log.setGlobalLevel(level);
						expect(log.globalState.globalLevel.get()).toBe(level);
					});
				}
			}


() => {
					const expected = log.globalState.globalLevel.get();

					log.setGlobalLevel('adfjakha' as any);

					expect(log.globalState.globalLevel.get()).toBe(expected);
				}


() => {
					expect(log.globalState.globalLevel.get()).not.toBe(Levels.NONE);

					log.setGlobalLevel(Levels.NONE);

					expect(log.globalState.globalLevel.get()).toBe(0);
				}


() => {
						expect(log.globalState.globalLevel.get()).not.toBe(level);
						log.setGlobalLevel(level);
						expect(log.globalState.globalLevel.get()).toBe(level);
					}


() => {
				const spy = jest.spyOn(log.globalState.globalLevel, 'enableLevel');
				expect(spy).not.toBeCalled();

				log.enableGlobalLevel(1);

				expect(spy).toBeCalled();
			}


() => {
				const spy = jest.spyOn(log.globalState.globalLevel, 'enableLevels');
				expect(spy).not.toBeCalled();

				log.enableGlobalLevels([1]);

				expect(spy).toBeCalled();
			}


() => {
				const spy = jest.spyOn(log.globalState.globalLevel, 'disableLevel');
				expect(spy).not.toBeCalled();

				log.disableGlobalLevel(1);

				expect(spy).toBeCalled();
			}


() => {
				const spy = jest.spyOn(log.globalState.globalLevel, 'disableLevels');
				expect(spy).not.toBeCalled();

				log.disableGlobalLevels([1]);

				expect(spy).toBeCalled();
			}


() => {
			describe('setGroupLevel', () => {
				beforeEach(() => {
					log.setGroupLevel(Levels.ERROR);
				});

				it('should not change group level when level arg is undefined', () => {
					log.groupState.level.set(Levels.TRACE);
					log.setGroupLevel(undefined as any);
					expect(log.groupState.level.get()).toBe(Levels.TRACE);
				});

				for (const level of LOG_LEVELS) {
					it(`should set group level to ${level} set to ${level}`, () => {
						expect(log.groupState.level.get()).toBe(Levels.ERROR);
						log.setGroupLevel(level);
						expect(log.groupState.level.get()).toBe(level);
					});
				}
			});

			it(`should call enableLogLevel`, () => {
				const spy = jest.spyOn(log.groupState.level, 'enableLevel');
				expect(spy).not.toBeCalled();

				log.enableGroupLevel(1);

				expect(spy).toBeCalled();
			});

			it(`should call enableMultipleLevels`, () => {
				const spy = jest.spyOn(log.groupState.level, 'enableLevels');
				expect(spy).not.toBeCalled();

				log.enableGroupLevels([1]);

				expect(spy).toBeCalled();
			});

			it(`should call disableLogLevel`, () => {
				const spy = jest.spyOn(log.groupState.level, 'disableLevel');
				expect(spy).not.toBeCalled();

				log.disableGroupLevel(1);

				expect(spy).toBeCalled();
			});

			it(`should call disableMultipleLevels`, () => {
				const spy = jest.spyOn(log.groupState.level, 'disableLevels');
				expect(spy).not.toBeCalled();

				log.disableGroupLevels([1]);

				expect(spy).toBeCalled();
			});
		}


() => {
				beforeEach(() => {
					log.setGroupLevel(Levels.ERROR);
				});

				it('should not change group level when level arg is undefined', () => {
					log.groupState.level.set(Levels.TRACE);
					log.setGroupLevel(undefined as any);
					expect(log.groupState.level.get()).toBe(Levels.TRACE);
				});

				for (const level of LOG_LEVELS) {
					it(`should set group level to ${level} set to ${level}`, () => {
						expect(log.groupState.level.get()).toBe(Levels.ERROR);
						log.setGroupLevel(level);
						expect(log.groupState.level.get()).toBe(level);
					});
				}
			}


() => {
					log.setGroupLevel(Levels.ERROR);
				}


() => {
					log.groupState.level.set(Levels.TRACE);
					log.setGroupLevel(undefined as any);
					expect(log.groupState.level.get()).toBe(Levels.TRACE);
				}


() => {
						expect(log.groupState.level.get()).toBe(Levels.ERROR);
						log.setGroupLevel(level);
						expect(log.groupState.level.get()).toBe(level);
					}


() => {
				const spy = jest.spyOn(log.groupState.level, 'enableLevel');
				expect(spy).not.toBeCalled();

				log.enableGroupLevel(1);

				expect(spy).toBeCalled();
			}


() => {
				const spy = jest.spyOn(log.groupState.level, 'enableLevels');
				expect(spy).not.toBeCalled();

				log.enableGroupLevels([1]);

				expect(spy).toBeCalled();
			}


() => {
				const spy = jest.spyOn(log.groupState.level, 'disableLevel');
				expect(spy).not.toBeCalled();

				log.disableGroupLevel(1);

				expect(spy).toBeCalled();
			}


() => {
				const spy = jest.spyOn(log.groupState.level, 'disableLevels');
				expect(spy).not.toBeCalled();

				log.disableGroupLevels([1]);

				expect(spy).toBeCalled();
			}


() => {
			const level = 1;

			it(`should return with a string message if msg.length > 1`, () => {
				const result = log['createMessage'](level, ['def'], 1, 2, 3, 4);

				expect(typeof result.message).toBe('string');
			});

			it(`should return with a string message if msg.length === 0`, () => {
				const result = log['createMessage'](level, ['def']);

				expect(typeof result.message).toBe('string');
			});

			it(`should return with a string message if msg is a single string`, () => {
				const result = log['createMessage'](level, ['def'], 'single string message');

				expect(typeof result.message).toBe('string');
			});

			it(`should return with a string message if msg is a single non string`, () => {
				const result = log['createMessage'](level, ['def'], {a: 'b'});

				expect(typeof result.message).toBe('string');
			});
		}


() => {
				const result = log['createMessage'](level, ['def'], 1, 2, 3, 4);

				expect(typeof result.message).toBe('string');
			}


() => {
				const result = log['createMessage'](level, ['def']);

				expect(typeof result.message).toBe('string');
			}


() => {
				const result = log['createMessage'](level, ['def'], 'single string message');

				expect(typeof result.message).toBe('string');
			}


() => {
				const result = log['createMessage'](level, ['def'], {a: 'b'});

				expect(typeof result.message).toBe('string');
			}


() => {
			const LogLevel = 0b1010;
			const ceLog = log.makeLog('canExecute', {level: LogLevel});

			it('should return false when transport arg is undefined', () => {
				const result = ceLog['canExecute'](ceLog, undefined as any, Levels.ALL);

				expect(result).toBe(false);
			});

			it('should return false when transport arg is null', () => {
				const result = ceLog['canExecute'](ceLog, null as any, Levels.ALL);

				expect(result).toBe(false);
			});

			it('should return false when group is not enabled', () => {
				ceLog.groupState.enabled = false;

				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), Levels.ALL);
				ceLog.groupState.enabled = true;

				expect(result).toBe(false);
			});

			const BadMsgLevels: any[] = [-1, 0, 0.5, 5.7, '1'];
			it.each(BadMsgLevels)(`should return false: msgLevel '%p' not a positive integer`, (level) => {
				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), level);

				expect(result).toBe(false);
			});

			it('should return false when global and group levels have no active levels', () => {
				ceLog.setGlobalLevel(0);
				ceLog.setGroupLevel(0);

				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), Levels.ALL);

				expect(result).toBe(false);
			});

			it(`should return false when transport level does not match active levels`, () => {
				TRANSPORT.level.set(0b0001);
				expect(TRANSPORT.level.get() & ceLog.groupState.level.get()).toBe(0);

				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), Levels.ALL);
				TRANSPORT.level.set(Levels.ALL);

				expect(result).toBe(false);
			});

			it(`should return false when msgLevel does not match transport level`, () => {
				const msgLevel = Levels.ALL_CUSTOM;
				expect(TRANSPORT.level.get() & msgLevel).toBe(0);

				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), msgLevel);

				expect(result).toBe(false);
			});

			it(`should return true when global/group, transport, and message all share a level`, () => {
				ceLog.setGroupLevel(Levels.ALL);
				const msgLevel = Levels.WARN;
				expect(msgLevel & TRANSPORT.level.get() & ceLog.groupState.level.get()).toBeGreaterThan(0);

				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), msgLevel);

				expect(result).toBe(true);
			});
		}


() => {
				const result = ceLog['canExecute'](ceLog, undefined as any, Levels.ALL);

				expect(result).toBe(false);
			}


() => {
				const result = ceLog['canExecute'](ceLog, null as any, Levels.ALL);

				expect(result).toBe(false);
			}


() => {
				ceLog.groupState.enabled = false;

				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), Levels.ALL);
				ceLog.groupState.enabled = true;

				expect(result).toBe(false);
			}


(level) => {
				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), level);

				expect(result).toBe(false);
			}


() => {
				ceLog.setGlobalLevel(0);
				ceLog.setGroupLevel(0);

				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), Levels.ALL);

				expect(result).toBe(false);
			}


() => {
				TRANSPORT.level.set(0b0001);
				expect(TRANSPORT.level.get() & ceLog.groupState.level.get()).toBe(0);

				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), Levels.ALL);
				TRANSPORT.level.set(Levels.ALL);

				expect(result).toBe(false);
			}


() => {
				const msgLevel = Levels.ALL_CUSTOM;
				expect(TRANSPORT.level.get() & msgLevel).toBe(0);

				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), msgLevel);

				expect(result).toBe(false);
			}


() => {
				ceLog.setGroupLevel(Levels.ALL);
				const msgLevel = Levels.WARN;
				expect(msgLevel & TRANSPORT.level.get() & ceLog.groupState.level.get()).toBeGreaterThan(0);

				const result = ceLog['canExecute'](ceLog, TRANSPORT.level.get(), msgLevel);

				expect(result).toBe(true);
			}


() => {
			let executeSpy: jest.SpyInstance;

			beforeAll(() => {
				executeSpy = jest.spyOn(TRANSPORT, 'execute');
				log.addTransport(TRANSPORT);
			});

			beforeEach(() => {
				ACTION.mockClear();
				executeSpy.mockClear();
			});

			it('should not attempt to execute any transports when msg level is 0', async () => {
				expect(executeSpy).not.toHaveBeenCalled();

				await log.log(Levels.NONE, '11111111111');

				expect(executeSpy).not.toHaveBeenCalled();
			});

			it('should not attempt to execute any transports when log is not enabled', async () => {
				log.groupState.enabled = false;
				expect(executeSpy).not.toHaveBeenCalled();

				await log.log(Levels.ALL, '33333333333');
				log.groupState.enabled = true;

				expect(executeSpy).not.toHaveBeenCalled();
			});

			it('should only execute transports matching log level', async () => {
				expect(ACTION).not.toHaveBeenCalled();
				TRANSPORT.level.set(Levels.DEBUG);
				log.setGlobalLevel(Levels.NONE);
				log.setGroupLevel(Levels.WARN);
				const oppositeTransport = new Transport('opposite', Levels.WARN, ACTION);
				log.clear();
				log.addTransport(TRANSPORT);
				log.addTransport(oppositeTransport);

				await log.log(Levels.WARN, '5555555555');
				log.removeTransport(oppositeTransport);

				expect(ACTION).toHaveBeenCalledTimes(1);

				TRANSPORT.level.set(Levels.ALL);
			});

			it(`should not throw when transport throws`, (done) => {
				log.enableGroupLevel(1);
				const transport = new Transport('SyncAction', 1, () => {
					throw Error('Sync Err');
				});
				const transportAsync = new Transport('AsyncAction', 1, async () => {
					throw Error('Async Err');
				});

				log.addTransport(transportAsync);
				log.addTransport(transport);

				log.log(1, 'throw')
					.catch((err) => {
						fail(err);
					})
					.finally(() => {
						log.clearAll();
						done();
					});
			});

			it(`should return list of failures when transports return false`, (done) => {
				log.enableGroupLevel(1);
				log.clearAll();
				const transport = new Transport('SyncAction', 1, () => {
					return false;
				});
				const transportAsync = new Transport('AsyncAction', 1, async () => {
					throw 'err';
				});

				log.addTransport(transportAsync);
				log.addTransport(transport);

				log.log(1, 'fails')
					.then((res) => {
						const expected = {
							SyncAction: false,
							AsyncAction: 'err'
						};
						expect(res).toEqual(expect.objectContaining(expected));
					})
					.catch((err) => {
						fail(err);
					})
					.finally(() => {
						log.clearAll();
						done();
					});
			});

			it(`should return true when transports return true`, (done) => {
				log.enableGroupLevel(1);
				log.clearAll();
				const transport = new Transport('SyncAction', 1, () => {
					return true;
				});
				const transportAsync = new Transport('AsyncAction', 1, async () => {
					return true;
				});

				log.addTransport(transportAsync);
				log.addTransport(transport);

				log.log(1, 'works')
					.then((res) => {
						expect(res).toBe(true);
					})
					.catch((err) => {
						fail(err);
					})
					.finally(() => {
						log.clearAll();
						done();
					});
			});

			it(`should call parent tranports`, async () => {
				log.clearAll();
				log.addTransport(TRANSPORT);
				const childLog = log.makeLog('child', {enabled: true, level: Levels.ALL});
				expect(ACTION).not.toHaveBeenCalled();

				await childLog.error('msg');

				expect(ACTION).toHaveBeenCalled();
			});

			it(`should not call parent tranports if child has transport with the same id`, async () => {
				log.clearAll();
				log.addTransport(TRANSPORT);
				const childLog = log.makeLog('child', {enabled: true, level: Levels.ALL});
				childLog.addTransport(TRANSPORT);
				expect(ACTION).not.toHaveBeenCalled();

				await childLog.error('msg');

				expect(ACTION).toHaveBeenCalledTimes(1);
			});
		}


() => {
				executeSpy = jest.spyOn(TRANSPORT, 'execute');
				log.addTransport(TRANSPORT);
			}


() => {
				ACTION.mockClear();
				executeSpy.mockClear();
			}


async () => {
				expect(executeSpy).not.toHaveBeenCalled();

				await log.log(Levels.NONE, '11111111111');

				expect(executeSpy).not.toHaveBeenCalled();
			}


async () => {
				log.groupState.enabled = false;
				expect(executeSpy).not.toHaveBeenCalled();

				await log.log(Levels.ALL, '33333333333');
				log.groupState.enabled = true;

				expect(executeSpy).not.toHaveBeenCalled();
			}


async () => {
				expect(ACTION).not.toHaveBeenCalled();
				TRANSPORT.level.set(Levels.DEBUG);
				log.setGlobalLevel(Levels.NONE);
				log.setGroupLevel(Levels.WARN);
				const oppositeTransport = new Transport('opposite', Levels.WARN, ACTION);
				log.clear();
				log.addTransport(TRANSPORT);
				log.addTransport(oppositeTransport);

				await log.log(Levels.WARN, '5555555555');
				log.removeTransport(oppositeTransport);

				expect(ACTION).toHaveBeenCalledTimes(1);

				TRANSPORT.level.set(Levels.ALL);
			}


(done) => {
				log.enableGroupLevel(1);
				const transport = new Transport('SyncAction', 1, () => {
					throw Error('Sync Err');
				});
				const transportAsync = new Transport('AsyncAction', 1, async () => {
					throw Error('Async Err');
				});

				log.addTransport(transportAsync);
				log.addTransport(transport);

				log.log(1, 'throw')
					.catch((err) => {
						fail(err);
					})
					.finally(() => {
						log.clearAll();
						done();
					});
			}


() => {
					throw Error('Sync Err');
				}


async () => {
					throw Error('Async Err');
				}


(err) => {
						fail(err);
					}


() => {
						log.clearAll();
						done();
					}


(done) => {
				log.enableGroupLevel(1);
				log.clearAll();
				const transport = new Transport('SyncAction', 1, () => {
					return false;
				});
				const transportAsync = new Transport('AsyncAction', 1, async () => {
					throw 'err';
				});

				log.addTransport(transportAsync);
				log.addTransport(transport);

				log.log(1, 'fails')
					.then((res) => {
						const expected = {
							SyncAction: false,
							AsyncAction: 'err'
						};
						expect(res).toEqual(expect.objectContaining(expected));
					})
					.catch((err) => {
						fail(err);
					})
					.finally(() => {
						log.clearAll();
						done();
					});
			}


() => {
					return false;
				}


async () => {
					throw 'err';
				}


(res) => {
						const expected = {
							SyncAction: false,
							AsyncAction: 'err'
						};
						expect(res).toEqual(expect.objectContaining(expected));
					}


(done) => {
				log.enableGroupLevel(1);
				log.clearAll();
				const transport = new Transport('SyncAction', 1, () => {
					return true;
				});
				const transportAsync = new Transport('AsyncAction', 1, async () => {
					return true;
				});

				log.addTransport(transportAsync);
				log.addTransport(transport);

				log.log(1, 'works')
					.then((res) => {
						expect(res).toBe(true);
					})
					.catch((err) => {
						fail(err);
					})
					.finally(() => {
						log.clearAll();
						done();
					});
			}


() => {
					return true;
				}


async () => {
					return true;
				}


(res) => {
						expect(res).toBe(true);
					}


async () => {
				log.clearAll();
				log.addTransport(TRANSPORT);
				const childLog = log.makeLog('child', {enabled: true, level: Levels.ALL});
				expect(ACTION).not.toHaveBeenCalled();

				await childLog.error('msg');

				expect(ACTION).toHaveBeenCalled();
			}


async () => {
				log.clearAll();
				log.addTransport(TRANSPORT);
				const childLog = log.makeLog('child', {enabled: true, level: Levels.ALL});
				childLog.addTransport(TRANSPORT);
				expect(ACTION).not.toHaveBeenCalled();

				await childLog.error('msg');

				expect(ACTION).toHaveBeenCalledTimes(1);
			}


() => {
			const logSpy = jest.spyOn(log, 'log');

			beforeEach(() => {
				logSpy.mockClear();
				expect(logSpy).not.toHaveBeenCalled();
			});

			afterAll(() => {
				logSpy.mockRestore();
			});

			for (const method of LOG_METHODS) {
				describe(`${method.name}`, () => {
					it('should call log method exactly once', () => {
						log[method.name](MOCK_MSG);

						expect(logSpy).toHaveBeenCalledTimes(1);
					});

					it(`should pass level '${method.level}' to log method`, () => {
						log[method.name](MOCK_MSG);

						expect(logSpy).toHaveBeenLastCalledWith(method.level, expect.anything());
						expect(logSpy).toHaveBeenCalledTimes(1);
					});

					it('should pass msg to log method', () => {
						const sampleMsg = 'AAA0814108';

						log[method.name](sampleMsg);

						expect(logSpy).toHaveBeenLastCalledWith(expect.anything(), sampleMsg);
						expect(logSpy).toHaveBeenCalledTimes(1);
					});
				});
			}
		}


() => {
				logSpy.mockClear();
				expect(logSpy).not.toHaveBeenCalled();
			}


() => {
				logSpy.mockRestore();
			}


() => {
					it('should call log method exactly once', () => {
						log[method.name](MOCK_MSG);

						expect(logSpy).toHaveBeenCalledTimes(1);
					});

					it(`should pass level '${method.level}' to log method`, () => {
						log[method.name](MOCK_MSG);

						expect(logSpy).toHaveBeenLastCalledWith(method.level, expect.anything());
						expect(logSpy).toHaveBeenCalledTimes(1);
					});

					it('should pass msg to log method', () => {
						const sampleMsg = 'AAA0814108';

						log[method.name](sampleMsg);

						expect(logSpy).toHaveBeenLastCalledWith(expect.anything(), sampleMsg);
						expect(logSpy).toHaveBeenCalledTimes(1);
					});
				}


() => {
						log[method.name](MOCK_MSG);

						expect(logSpy).toHaveBeenCalledTimes(1);
					}


() => {
						log[method.name](MOCK_MSG);

						expect(logSpy).toHaveBeenLastCalledWith(method.level, expect.anything());
						expect(logSpy).toHaveBeenCalledTimes(1);
					}


() => {
						const sampleMsg = 'AAA0814108';

						log[method.name](sampleMsg);

						expect(logSpy).toHaveBeenLastCalledWith(expect.anything(), sampleMsg);
						expect(logSpy).toHaveBeenCalledTimes(1);
					}


async ({ context }) => {
    return await getApmIndexSettings({ context });
  }


async ({ context }) => {
    return await getApmIndices({
      savedObjectsClient: context.core.savedObjects.client,
      config: context.config,
    });
  }


async ({ context }) => {
    const { body } = context.params;
    const savedObjectsClient = context.core.savedObjects.client;
    return await saveApmIndices(savedObjectsClient, body);
  }


({ url }) => {
  const editUrl = `${githubRepoUrl}${url}.md`

  return (

      Эту страницу можно улучшить на Github


(e: LayoutChangeEvent) => {
    if (this.state.twidth) {
      return;
    }

    this.setState(
      {
        twidth: e.nativeEvent.layout.width,
      },
      () => {
        // onLayout may be earlier than onLayoutContainer on android, can not be sure width < twidth at that time.
        this.tryStart();
      },
    );
  }


() => {
        // onLayout may be earlier than onLayoutContainer on android, can not be sure width < twidth at that time.
        this.tryStart();
      }


(e: LayoutChangeEvent) => {
    if (!this.state.width) {
      this.setState(
        {
          width: e.nativeEvent.layout.width,
        },
        () => {
          this.left.setValue(0);
          this.tryStart();
        },
      );
    }
  }


() => {
          this.left.setValue(0);
          this.tryStart();
        }


() => {
    const { fps = 40, loop } = this.props;
    const SPPED = (1 / fps) * 1000;
    // tslint:disable-next-line:no-this-assignment
    const { props } = this;
    Animated.timing(this.left, {
      toValue: 1,
      duration: this.state.twidth * SPPED,
      easing: Easing.linear,
      delay: props.leading,
      isInteraction: false,
      useNativeDriver: true,
    }).start(() => {
      if (loop) {
        this.moveToHeader();
      }
    });
  }


() => {
      if (loop) {
        this.moveToHeader();
      }
    }


() => {
    Animated.timing(this.left, {
      toValue: 0,
      duration: 0,
      delay: this.props.trailing,
      isInteraction: false,
      useNativeDriver: true,
    }).start(() => {
      this.startMove();
    });
  }


() => {
      this.startMove();
    }


class Marquee extends React.PureComponent<MarqueeProps, any> {
  static defaultProps = {
    text: '',
    loop: false,
    leading: 500,
    trailing: 800,
    fps: 40,
    maxWidth: 1000,
  };

  texts: any;
  left: any;

  constructor(props: MarqueeProps) {
    super(props);

    this.texts = {};
    this.left = new Animated.Value(0);
    this.state = {
      twidth: 0,
      width: 0,
    };
  }

  onLayout = (e: LayoutChangeEvent) => {
    if (this.state.twidth) {
      return;
    }

    this.setState(
      {
        twidth: e.nativeEvent.layout.width,
      },
      () => {
        // onLayout may be earlier than onLayoutContainer on android, can not be sure width < twidth at that time.
        this.tryStart();
      },
    );
  };

  tryStart() {
    if (this.state.twidth > this.state.width && this.state.width) {
      this.startMove();
    }
  }

  onLayoutContainer = (e: LayoutChangeEvent) => {
    if (!this.state.width) {
      this.setState(
        {
          width: e.nativeEvent.layout.width,
        },
        () => {
          this.left.setValue(0);
          this.tryStart();
        },
      );
    }
  };

  startMove = () => {
    const { fps = 40, loop } = this.props;
    const SPPED = (1 / fps) * 1000;
    // tslint:disable-next-line:no-this-assignment
    const { props } = this;
    Animated.timing(this.left, {
      toValue: 1,
      duration: this.state.twidth * SPPED,
      easing: Easing.linear,
      delay: props.leading,
      isInteraction: false,
      useNativeDriver: true,
    }).start(() => {
      if (loop) {
        this.moveToHeader();
      }
    });
  };

  moveToHeader = () => {
    Animated.timing(this.left, {
      toValue: 0,
      duration: 0,
      delay: this.props.trailing,
      isInteraction: false,
      useNativeDriver: true,
    }).start(() => {
      this.startMove();
    });
  };

  render() {
    const { width, twidth } = this.state;
    const { style, text, maxWidth } = this.props;

    const textChildren = (
      <Text
        onLayout={this.onLayout}
        numberOfLines={1}
        ellipsizeMode="tail"
        style={style}
      >
        {text}
      </Text>
    );

    return (
      <View
        style={{ flex: 1, flexDirection: 'row', alignItems: 'center' }}
        onLayout={this.onLayoutContainer}
      >
        <Animated.View
          // tslint:disable-next-line:jsx-no-multiline-js
          style=


export interface MarqueeProps {
  text?: React.ReactNode;
  loop?: boolean;
  leading?: number;
  trailing?: number;
  className?: string;
  fps?: number;
  style?: StyleProp<TextStyle>;
  maxWidth?: number;
}


tryStart() {
    if (this.state.twidth > this.state.width && this.state.width) {
      this.startMove();
    }
  }


render() {
    const { width, twidth } = this.state;
    const { style, text, maxWidth } = this.props;

    const textChildren = (
      <Text
        onLayout={this.onLayout}
        numberOfLines={1}
        ellipsizeMode="tail"
        style={style}
      >
        {text}
      </Text>
    );

    return (
      <View
        style={{ flex: 1, flexDirection: 'row', alignItems: 'center' }}


() => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [UserCredentialResolver]
    });
  });

  it('should ...', inject([UserCredentialResolver], (service: UserCredentialResolver) => {
    expect(service).toBeTruthy();
  }));
}


() => {
    TestBed.configureTestingModule({
      providers: [UserCredentialResolver]
    });
  }


(service: UserCredentialResolver) => {
    expect(service).toBeTruthy();
  }


(child) => {
      child.setParent(this);
      this.children.push(child);
      child.styleNode &&
        this.styleNode &&
        !this.styleNode.originChildren.includes(child.styleNode) &&
        this.styleNode.originChildren.push(child.styleNode);
    }


(s) => s !== ''


(child) => child.mount()


(child) => child.unmount()


(child) => child.render()


(child) => {
      child.clearLayout();
    }


(e) => {
    let shape = e.target;
    while (shape && !shape.get('uiNode')) {
      shape = shape.get('parent');
    }
    e.targetGNode = shape || null;
    e.uiNode = shape?.get('uiNode') ?? null;
    this.events[e.type]?.forEach((fn) => fn(e, this));
  }


(fn) => fn(e, this)


setParent(parent) {
    this.parent = parent;
  }


appendChild(...list) {
    list.forEach((child) => {
      child.setParent(this);
      this.children.push(child);
      child.styleNode &&
        this.styleNode &&
        !this.styleNode.originChildren.includes(child.styleNode) &&
        this.styleNode.originChildren.push(child.styleNode);
    });
    this.reflow();
  }


removeChild(child) {
    if (!child) return;
    child.remove();
  }


remove() {
    const parent = this.parent;
    this.gNode?.remove();
    if (parent) {
      parent.children.splice(1, parent.children.indexOf(this));
      parent.styleNode?.children.splice(1, parent.children.indexOf(this.styleNode));
      if (this.isMounted) parent.reflow();
    }
    if (this.isMounted) this.unmount();
  }


query(selector) {
    if (typeof selector !== 'string') return;
    const arr = selector.split(/\s+/g).filter((s) => s !== '');
    const stack: any = [[this, arr]];
    while (stack.length) {
      const [uiNode, selectorArr] = stack.shift();
      for (const child of uiNode.children) {
        let rest = [];
        if (child.styleNode && isSelectorMatchDom(child.styleNode.dom, selectorArr[0])) {
          if (selectorArr.slice(1).length === 0) {
            return child;
          } else {
            rest = selectorArr.slice(1);
          }
        } else {
          rest = selectorArr;
        }
        stack.push([child, rest]);
      }
    }
  }


queryAll(selector) {
    if (typeof selector !== 'string') return;
    const arr = selector.split(/\s+/g).filter((s) => s !== '');
    const result = [];
    const stack: any = [[this, arr, result]];
    while (stack.length) {
      const [uiNode, selectorArr, result] = stack.shift();
      for (const child of uiNode.children) {
        let rest = [];
        if (child.styleNode && isSelectorMatchDom(child.styleNode.dom, selectorArr[0])) {
          if (selectorArr.slice(1).length === 0) {
            result.push(child);
            rest = [selectorArr[0]];
          } else {
            rest = selectorArr.slice(1);
          }
        } else {
          rest = selectorArr;
        }
        stack.push([child, rest, result]);
      }
    }
    return result;
  }


// 手动挂载G节点
private manualMount(parentGNode) {
    this.parentGNode = parentGNode;
    this.layout();
    this.mount();
  }


reflow() {
    // 节点没有挂载到G上
    if (!this.parentGNode) return;

    // 上浮到absolute或根节点
    if (this.style?.position !== 'absolute' && this.parent) {
      this.parent.reflow();
      return;
    }

    // 开始重排
    this.layout();
    this.render();
  }


// 计算布局
layout() {
    this._prevLayout = { ...(this._layout || {}) };
    this.clearLayout();
    computeLayout(this.styleNode);
    return;
  }


mount() {
    if (this.isMounted) {
      return;
    }

    if (this.style?.display === 'none') {
      this.isDisplay = false;
      return;
    }
    // 保存之后会对比
    this._prevAttrs = this.attributes;
    this._prevStyle = this.style;

    this.draw(this.parentGNode);
    this.isMounted = true;
    this.gNode.set('uiNode', this);
    this.gNode.on('*', this.trigger);

    this.children.forEach((child) => child.mount());
    this.didMount();
  }


// 全部draw一遍后触发下
didMount() {}


unmount() {
    if (!this.isMounted) return;
    this.isMounted = false;
    this.children.forEach((child) => child.unmount());
    this.didUnmount();
  }


didUnmount() {}


private render() {
    if (!this.isMounted) {
      this.mount();
      return;
    }
    // if (!this.shouldUpdate(this._prevAttrs, this._prevStyle)) return;
    // 处理display的情况
    if (this.style?.display === 'none') {
      this.isDisplay = false;
      this.gNode?.remove(false);
      return false;
    }

    if (this.isDisplay === false) {
      this.isDisplay = true;
      this.parentGNode?.add(this.gNode);
    }
    const should = this.shouldUpdate(this._prevAttrs, this._prevStyle, this._prevLayout);
    should && this.draw();
    this.children.forEach((child) => child.render());
    should && this.didUpdate();
  }


didUpdate() {}


shouldUpdate(prevAttr, prevStyle, prevLayout) {
    return true;
  }


draw(parentGNode?) {}


animate() {}


private clearLayout() {
    this.styleNode.isDirty = true;
    this.children.forEach((child) => {
      child.clearLayout();
    });
  }


setAttribute(key, value) {
    if (this.styleNode && this.styleNode.dom) {
      this._prevAttrs = { ...this.styleNode.dom.attrs };
      this.styleNode.dom.attrs[key] = value;
      if (!this.parent?.isMounted) return;
      this.render();
    }
  }


setStyle(key, value) {
    if (this.styleNode && this.styleNode.style) {
      this._prevStyle = { ...this.styleNode.dom.style };
      this.styleNode.style[key] = value;
      if (this.parent && !this.parent.isMounted) return;
      if (reflowAttrs[key]) {
        this.reflow();
      } else {
        this.render();
      }
    }
  }


getAttribute(key) {
    return this.styleNode?.dom?.attrs[key];
  }


getStyle(key) {
    return this.styleNode?.layout[key] ?? this.styleNode?.style[key];
  }


setText(text) {
    const textNode = this.query('text');
    if (textNode && textNode.styleNode && textNode.styleNode.dom) {
      textNode.styleNode.dom.text = text;
      textNode.render();
    }
  }


on(eventName, fn) {
    this.events[eventName] = [...(this.events[eventName] || []), fn];
  }


off(eventName, fn) {
    if (!fn) {
      delete this.events[eventName];
      return;
    }
    const events = this.events[eventName];
    const index = events?.indexOf(fn);
    if (index && index !== -1) events?.splice(index, 1);
  }


r => r === claim


@Injectable({
  providedIn: ServicesModule
})
export class AuthService {
  private static ANONYMOUS = 'anonymous';
  private static TOKEN_KEY = 'token_key';

  private _token: IToken;
  private _username: string = AuthService.ANONYMOUS;
  private _claims: Array<string> = new Array<string>();

  public onAuthenticated: EventEmitter<boolean> = new EventEmitter<boolean>();

  public get isAuthenticated(): boolean {
    // TODO: check also expiration!

    return this._token
      ? true
      : false;
  }

  public get username(): string {
    return this._username;
  }

  public get claims(): Array<string> {
    return this._claims;
  }

  public constructor(
    private _storage: StorageService
  ) {
    this.tryAuthenticate();
  }

  public getToken(): string {
    if (this._token) {
      return this._token.access_token;
    }

    const storedToken = this._storage
      .getItem<IToken>(AuthService.TOKEN_KEY);
    if (storedToken) {
      this.authenticate(storedToken);
      return this._token.access_token;
    }
  }

  public authenticate(token: IToken): void {
    if (token) {
      this._token = token;
      this._storage.setItem(AuthService.TOKEN_KEY, this._token);

      this.setProperties();

      this.onAuthenticated.next(this.isAuthenticated);
    }
  }

  public logout(): void {
    this._storage.removeItem(AuthService.TOKEN_KEY);
    delete this._token;

    this.onAuthenticated.next(this.isAuthenticated);
  }

  public hasClaim(claim: string): boolean {
    if (!this._claims || !claim) {
      return false;
    }

    return this._claims.some((r => r === claim));
  }

  public tryAuthenticate(): void {
    const token = this._storage.getItem<IToken>(AuthService.TOKEN_KEY);
    if (token) {
      // TODO: check expiration!!!

      this.authenticate(token);
    }
  }

  public setClaims(claims: string[]): void {
    this._claims = claims;
  }

  private setProperties(): void {
    if (this._token) {
      const jwt = JSON.parse(window.atob(this._token.access_token.split('.')[1]));

      this._username = jwt.name;

      this._claims = Array.isArray(jwt.role)
        ? jwt.role
        : [jwt.role];

      return;
    }

    this._username = AuthService.ANONYMOUS;
    this._claims = new Array<string>();
  }
}


export interface IToken {
  access_token: string;
  expires_in: number;
  token_type: string;
}


public getToken(): string {
    if (this._token) {
      return this._token.access_token;
    }

    const storedToken = this._storage
      .getItem<IToken>(AuthService.TOKEN_KEY);
    if (storedToken) {
      this.authenticate(storedToken);
      return this._token.access_token;
    }
  }


public authenticate(token: IToken): void {
    if (token) {
      this._token = token;
      this._storage.setItem(AuthService.TOKEN_KEY, this._token);

      this.setProperties();

      this.onAuthenticated.next(this.isAuthenticated);
    }
  }


public logout(): void {
    this._storage.removeItem(AuthService.TOKEN_KEY);
    delete this._token;

    this.onAuthenticated.next(this.isAuthenticated);
  }


public hasClaim(claim: string): boolean {
    if (!this._claims || !claim) {
      return false;
    }

    return this._claims.some((r => r === claim));
  }


public tryAuthenticate(): void {
    const token = this._storage.getItem<IToken>(AuthService.TOKEN_KEY);
    if (token) {
      // TODO: check expiration!!!

      this.authenticate(token);
    }
  }


public setClaims(claims: string[]): void {
    this._claims = claims;
  }


private setProperties(): void {
    if (this._token) {
      const jwt = JSON.parse(window.atob(this._token.access_token.split('.')[1]));

      this._username = jwt.name;

      this._claims = Array.isArray(jwt.role)
        ? jwt.role
        : [jwt.role];

      return;
    }

    this._username = AuthService.ANONYMOUS;
    this._claims = new Array<string>();
  }


export function EnrollmentReminder() {
  return (
    <>

        <Typography
          id="enrollment-reminder"
          tag="h2"
          variant="h3"
          className="uppercase tracking-wide"
        >
          {i18next.t("site.enrollment-reminder")}
        </Typography>
        <Typography
          tag="h3"
          variant="h2"
          weight="base"
          className="font-normal mt-4"
        >
          {i18next.t("site.enrollment-reminder-guide1")}
        </Typography>

          <Typography tag="p" variant="p" className="mt-4">
            {i18next.t("site.enrollment-reminder-guide2")}
          </Typography>
          <Link
            className="mt-6 w-full pt-2 pb-2 md:w-1/2"
            variant="primary"
            to={`/ics/enroll_${i18next.language || "es"}.ics`}


(_request: http.IncomingMessage) => {
  return Promise.resolve('myChannel');
}


() => console.log('ws open')


(data) => console.log(`received message: ${data}`)


() => {
  broker.publish('myChannel', 'test data');
}


export type NumOrString = number | string;


export type NumOrExpression = number | ExpressionQualifier;


export type StringOrExpression = string | ExpressionQualifier;


export type StringNumberOrExpression = string | number | ExpressionQualifier;


/**
 * [M] 网络连接
 * - [用法] 这里只是给出了一个样例,实际使用中http请求需要更加定制化
 * - [注意] 考虑await无法对reject()进行处理,需要进行try-catch封装,并在catch中返回null
 * - [注意] 需要处理浏览器跨域请求;如果是cros方案,需要后端(目标url)进行配合才可以实现
 */
export class MHttp {

    /**
     * fetch+post+json
     * @param url
     * @param body 建议前后端使用interface规定类型
     */
    static async fetch_post_json(url: string, body: object): Promise<object> {
        try {
            let response = await fetch(url, {
                method: "POST",
                mode: "cors",
                headers: new Headers({ 'Content-Type': 'application/json' }),
                body: JSON.stringify(body),
            })
            let json = await response.json()
            return json
        } catch (error) {
            MLog.error(error)
            return null
        }
    }

}


/**
     * fetch+post+json
     * @param url
     * @param body 建议前后端使用interface规定类型
     */
static async fetch_post_json(url: string, body: object): Promise<object> {
        try {
            let response = await fetch(url, {
                method: "POST",
                mode: "cors",
                headers: new Headers({ 'Content-Type': 'application/json' }),
                body: JSON.stringify(body),
            })
            let json = await response.json()
            return json
        } catch (error) {
            MLog.error(error)
            return null
        }
    }


export function isCancel(value: any) {
    return value instanceof Cancel
}


export default class Cancel {
    message?: string
    constructor(message?: string) {
        this.message = message
    }
}


/**
 *
Sets the Cluster$VisibleToAllUsers value, which determines whether the
 *          cluster is visible to all IAM users of the AWS account associated with the cluster. Only
 *          the IAM user who created the cluster or the AWS account root user can call this action. The
 *          default value, true, indicates that all IAM users in the AWS account can
 *          perform cluster actions if they have the proper IAM policy permissions. If set to
 *             false, only the IAM user that created the cluster can perform actions. This
 *          action works on running clusters. You can override the default true setting
 *          when you create a cluster by using the VisibleToAllUsers parameter with
 *             RunJobFlow.

 */
export class SetVisibleToAllUsersCommand extends $Command<
  SetVisibleToAllUsersCommandInput,
  SetVisibleToAllUsersCommandOutput,
  EMRClientResolvedConfig
> {
  // Start section: command_properties
  // End section: command_properties

  constructor(readonly input: SetVisibleToAllUsersCommandInput) {
    // Start section: command_constructor
    super();
    // End section: command_constructor
  }

  /**
   * @internal
   */
  resolveMiddleware(
    clientStack: MiddlewareStack<ServiceInputTypes, ServiceOutputTypes>,
    configuration: EMRClientResolvedConfig,
    options?: __HttpHandlerOptions
  ): Handler<SetVisibleToAllUsersCommandInput, SetVisibleToAllUsersCommandOutput> {
    this.middlewareStack.use(getSerdePlugin(configuration, this.serialize, this.deserialize));

    const stack = clientStack.concat(this.middlewareStack);

    const { logger } = configuration;
    const clientName = "EMRClient";
    const commandName = "SetVisibleToAllUsersCommand";
    const handlerExecutionContext: HandlerExecutionContext = {
      logger,
      clientName,
      commandName,
      inputFilterSensitiveLog: SetVisibleToAllUsersInput.filterSensitiveLog,
      outputFilterSensitiveLog: (output: any) => output,
    };
    const { requestHandler } = configuration;
    return stack.resolve(
      (request: FinalizeHandlerArguments<any>) =>
        requestHandler.handle(request.request as __HttpRequest, options || {}),
      handlerExecutionContext
    );
  }

  private serialize(input: SetVisibleToAllUsersCommandInput, context: __SerdeContext): Promise<__HttpRequest> {
    return serializeAws_json1_1SetVisibleToAllUsersCommand(input, context);
  }

  private deserialize(output: __HttpResponse, context: __SerdeContext): Promise<SetVisibleToAllUsersCommandOutput> {
    return deserializeAws_json1_1SetVisibleToAllUsersCommand(output, context);
  }

  // Start section: command_body_extra
  // End section: command_body_extra
}


export type SetVisibleToAllUsersCommandInput = SetVisibleToAllUsersInput;


export type SetVisibleToAllUsersCommandOutput = __MetadataBearer;


/**
   * @internal
   */
resolveMiddleware(
    clientStack: MiddlewareStack<ServiceInputTypes, ServiceOutputTypes>,
    configuration: EMRClientResolvedConfig,
    options?: __HttpHandlerOptions
  ): Handler<SetVisibleToAllUsersCommandInput, SetVisibleToAllUsersCommandOutput> {
    this.middlewareStack.use(getSerdePlugin(configuration, this.serialize, this.deserialize));

    const stack = clientStack.concat(this.middlewareStack);

    const { logger } = configuration;
    const clientName = "EMRClient";
    const commandName = "SetVisibleToAllUsersCommand";
    const handlerExecutionContext: HandlerExecutionContext = {
      logger,
      clientName,
      commandName,
      inputFilterSensitiveLog: SetVisibleToAllUsersInput.filterSensitiveLog,
      outputFilterSensitiveLog: (output: any) => output,
    };
    const { requestHandler } = configuration;
    return stack.resolve(
      (request: FinalizeHandlerArguments<any>) =>
        requestHandler.handle(request.request as __HttpRequest, options || {}),
      handlerExecutionContext
    );
  }


private serialize(input: SetVisibleToAllUsersCommandInput, context: __SerdeContext): Promise<__HttpRequest> {
    return serializeAws_json1_1SetVisibleToAllUsersCommand(input, context);
  }


private deserialize(output: __HttpResponse, context: __SerdeContext): Promise<SetVisibleToAllUsersCommandOutput> {
    return deserializeAws_json1_1SetVisibleToAllUsersCommand(output, context);
  }


({ appointments }: any) => {
    return (
        <>
            {!appointments.length && <Text style={styles.emptyList}>No hay citas disponibles</Text>}
            <FlatList
                data={appointments}
                renderItem={({ item }: any)


(state: any) => ({ appointments: state.appointments })


async function bootstrap() {
  const app = createApp(App);

  // Configure store
  setupStore(app);

  // Initialize internal system configuration
  initAppConfigStore();

  // Register global components
  registerGlobComp(app);

  // Multilingual configuration
  // Asynchronous case: language files may be obtained from the server side
  await setupI18n(app);

  // 使用vue.use使用了一下router组件
  // Configure routing
  setupRouter(app);

  // 路由拦截器
  // router-guard
  setupRouterGuard(router);

  // Register global directive
  setupGlobDirectives(app);

  // Configure global error handling
  setupErrorHandle(app);

  // https://next.router.vuejs.org/api/#isready
  // await router.isReady();

  app.mount('#app');
}


export class PopupTextCellEditor extends TextCellEditor {

    public isPopup(): boolean {
        return true;
    }

}


public isPopup(): boolean {
        return true;
    }


({}: RootNavigationProps) => {
  const navTheme = DefaultTheme;
  navTheme.colors.background = '#FAFCFC';

  return (
    <NavigationContainer>
      <RootStack.Navigator
        initialRouteName={'StartPage'}
        screenOptions={{
          headerShown: false,
        }}


export interface RootNavigationProps {}


export type RootStackParamList = {
  ProfileDetailPage: undefined;
  ProfileEditPage: undefined;
  ProfileListPage: undefined;
  RoomDetailPage: undefined;
  RoomListPage: undefined;
  SignInPage: undefined;
  SignUpPage: undefined;
  StartPage: undefined;
};


(
	square: string,
	ignore_list: { rank_offset: number; file_offset: number }[]
) => {
	let squares = [];
	let rank = parseInt(square.split('-')[0]);
	let file = parseInt(square.split('-')[1]);

	for (let i = rank - 1; i <= rank + 1; i++) {
		for (let j = file - 1; j <= file + 1; j++) {
			let valid_square = !isSquareOutOfBounds(i, j);
			ignore_list.forEach((item) => {
				valid_square =
					valid_square &&
					(i != rank + item.rank_offset || j != file + item.file_offset);
			});

			if (valid_square) {
				squares.push({
					rank: i,
					file: j,
				});
			}
		}
	}

	return squares;
}


(item) => {
				valid_square =
					valid_square &&
					(i != rank + item.rank_offset || j != file + item.file_offset);
			}


(rank: number, file: number) => {
	return (
		isNaN(rank) ||
		isNaN(file) ||
		rank < RANK_1 ||
		rank > RANK_9 ||
		file < FILE_1 ||
		file > FILE_9
	);
}


(
	board: Array<Array<Array<Piece | null>>>,
	square: string,
	depth: number,
	directions: boolean[]
) => {
	let rank = parseInt(square.split('-')[0]);
	let file = parseInt(square.split('-')[1]);

	let squares = [];
	let found = Array(8).fill(false);
	let probes = Array(8).fill(null);

	for (let i = 1; i <= depth; i++) {
		probes.splice(0, 0, {
			rank: rank,
			file: file + i,
		});
		probes.splice(1, 0, {
			rank: rank,
			file: file - i,
		});
		probes.splice(2, 0, {
			rank: rank + i,
			file: file,
		});
		probes.splice(3, 0, {
			rank: rank - i,
			file: file,
		});
		probes.splice(4, 0, {
			rank: rank + i,
			file: file + i,
		});
		probes.splice(5, 0, {
			rank: rank + i,
			file: file - i,
		});
		probes.splice(6, 0, {
			rank: rank - i,
			file: file + i,
		});
		probes.splice(7, 0, {
			rank: rank - i,
			file: file - i,
		});

		for (let j = 0; j < 8; j++) {
			if (
				directions[j] &&
				!isSquareOutOfBounds(probes[j].rank, probes[j].file) &&
				!found[j]
			) {
				squares.push(probes[j]);
				found[j] =
					get_top(board, probes[j].rank + '-' + probes[j].file) !== null;
			}
		}
	}

	return squares;
}


(
	board: Array<Array<Array<Piece | null>>>,
	probes: { rank: number; file: number }[],
	src: { piece: Piece | null; tier: number },
	square: string,
	turn: 'w' | 'b'
) => {
	let moves: RelaxMove[] = [];

	probes.forEach((x) => {
		let pos = x.rank + '-' + x.file;
		let dst = get_top(board, pos);

		if (dst === null) {
			moves.push({
				src: square,
				dst: pos,
				type: MOVEMENT,
			});
		} else {
			if (
				dst.tier < 3 &&
				dst.piece?.type != MARSHAL &&
				src.piece?.type != FORTRESS
			) {
				// pieces can't stack on marshall and fortress can't stack on other pieces
				moves.push({
					src: square,
					dst: pos,
					type: STACK,
				});
			}
			if (dst.piece?.color !== turn) {
				moves.push({
					src: square,
					dst: pos,
					type: ATTACK,
				});
			}
		}
	});

	return moves;
}


(x) => {
		let pos = x.rank + '-' + x.file;
		let dst = get_top(board, pos);

		if (dst === null) {
			moves.push({
				src: square,
				dst: pos,
				type: MOVEMENT,
			});
		} else {
			if (
				dst.tier < 3 &&
				dst.piece?.type != MARSHAL &&
				src.piece?.type != FORTRESS
			) {
				// pieces can't stack on marshall and fortress can't stack on other pieces
				moves.push({
					src: square,
					dst: pos,
					type: STACK,
				});
			}
			if (dst.piece?.color !== turn) {
				moves.push({
					src: square,
					dst: pos,
					type: ATTACK,
				});
			}
		}
	}


/**
 *
Searches the subfolders in a folder.

 * @example
 * Use a bare-bones client and the command you need to make an API call.
 * ```javascript
 * import { QuickSightClient, SearchFoldersCommand } from "@aws-sdk/client-quicksight"; // ES Modules import
 * // const { QuickSightClient, SearchFoldersCommand } = require("@aws-sdk/client-quicksight"); // CommonJS import
 * const client = new QuickSightClient(config);
 * const command = new SearchFoldersCommand(input);
 * const response = await client.send(command);
 * ```
 *
 * @see {@link SearchFoldersCommandInput} for command's `input` shape.
 * @see {@link SearchFoldersCommandOutput} for command's `response` shape.
 * @see {@link QuickSightClientResolvedConfig | config} for command's `input` shape.
 *
 */
export class SearchFoldersCommand extends $Command<
  SearchFoldersCommandInput,
  SearchFoldersCommandOutput,
  QuickSightClientResolvedConfig
> {
  // Start section: command_properties
  // End section: command_properties

  constructor(readonly input: SearchFoldersCommandInput) {
    // Start section: command_constructor
    super();
    // End section: command_constructor
  }

  /**
   * @internal
   */
  resolveMiddleware(
    clientStack: MiddlewareStack<ServiceInputTypes, ServiceOutputTypes>,
    configuration: QuickSightClientResolvedConfig,
    options?: __HttpHandlerOptions
  ): Handler<SearchFoldersCommandInput, SearchFoldersCommandOutput> {
    this.middlewareStack.use(getSerdePlugin(configuration, this.serialize, this.deserialize));

    const stack = clientStack.concat(this.middlewareStack);

    const { logger } = configuration;
    const clientName = "QuickSightClient";
    const commandName = "SearchFoldersCommand";
    const handlerExecutionContext: HandlerExecutionContext = {
      logger,
      clientName,
      commandName,
      inputFilterSensitiveLog: SearchFoldersRequest.filterSensitiveLog,
      outputFilterSensitiveLog: SearchFoldersResponse.filterSensitiveLog,
    };
    const { requestHandler } = configuration;
    return stack.resolve(
      (request: FinalizeHandlerArguments<any>) =>
        requestHandler.handle(request.request as __HttpRequest, options || {}),
      handlerExecutionContext
    );
  }

  private serialize(input: SearchFoldersCommandInput, context: __SerdeContext): Promise<__HttpRequest> {
    return serializeAws_restJson1SearchFoldersCommand(input, context);
  }

  private deserialize(output: __HttpResponse, context: __SerdeContext): Promise<SearchFoldersCommandOutput> {
    return deserializeAws_restJson1SearchFoldersCommand(output, context);
  }

  // Start section: command_body_extra
  // End section: command_body_extra
}


export interface SearchFoldersCommandInput extends SearchFoldersRequest {}


export interface SearchFoldersCommandOutput extends SearchFoldersResponse, __MetadataBearer {}


/**
   * @internal
   */
resolveMiddleware(
    clientStack: MiddlewareStack<ServiceInputTypes, ServiceOutputTypes>,
    configuration: QuickSightClientResolvedConfig,
    options?: __HttpHandlerOptions
  ): Handler<SearchFoldersCommandInput, SearchFoldersCommandOutput> {
    this.middlewareStack.use(getSerdePlugin(configuration, this.serialize, this.deserialize));

    const stack = clientStack.concat(this.middlewareStack);

    const { logger } = configuration;
    const clientName = "QuickSightClient";
    const commandName = "SearchFoldersCommand";
    const handlerExecutionContext: HandlerExecutionContext = {
      logger,
      clientName,
      commandName,
      inputFilterSensitiveLog: SearchFoldersRequest.filterSensitiveLog,
      outputFilterSensitiveLog: SearchFoldersResponse.filterSensitiveLog,
    };
    const { requestHandler } = configuration;
    return stack.resolve(
      (request: FinalizeHandlerArguments<any>) =>
        requestHandler.handle(request.request as __HttpRequest, options || {}),
      handlerExecutionContext
    );
  }


private serialize(input: SearchFoldersCommandInput, context: __SerdeContext): Promise<__HttpRequest> {
    return serializeAws_restJson1SearchFoldersCommand(input, context);
  }


private deserialize(output: __HttpResponse, context: __SerdeContext): Promise<SearchFoldersCommandOutput> {
    return deserializeAws_restJson1SearchFoldersCommand(output, context);
  }


() => {
  it('default', () => {
    const expectedList = [
      { id: 'hkY7o3DlYB2', text: 'What is Lorem Ipsum?', name: 'h1' },
      { id: 'h4AL9B4qAV6', text: 'Where does it come from?', name: 'h2' },
      { id: 'hBwwL6rm8B7', text: 'Why do we use it?', name: 'h3' },
    ]

    const result = createTableOfContents(content)
    expect(result).toStrictEqual(expectedList)
  })

  it('If `tags` is `h2, h4`', () => {
    const expectedList = [
      { id: 'h4AL9B4qAV6', text: 'Where does it come from?', name: 'h2' },
      { id: 'rdAK6TEAQqx', text: 'Where can I get some?', name: 'h4' },
    ]

    const result = createTableOfContents(content, { tags: 'h2, h4' })
    expect(result).toStrictEqual(expectedList)
  })

  it('disabled `dataForName`', () => {
    const expectedList = [
      { id: 'hkY7o3DlYB2', text: 'What is Lorem Ipsum?' },
      { id: 'h4AL9B4qAV6', text: 'Where does it come from?' },
      { id: 'hBwwL6rm8B7', text: 'Why do we use it?' },
    ]

    const result = createTableOfContents(content, { dataForName: false })
    expect(result).toStrictEqual(expectedList)
  })
}


() => {
    const expectedList = [
      { id: 'hkY7o3DlYB2', text: 'What is Lorem Ipsum?', name: 'h1' },
      { id: 'h4AL9B4qAV6', text: 'Where does it come from?', name: 'h2' },
      { id: 'hBwwL6rm8B7', text: 'Why do we use it?', name: 'h3' },
    ]

    const result = createTableOfContents(content)
    expect(result).toStrictEqual(expectedList)
  }


() => {
    const expectedList = [
      { id: 'h4AL9B4qAV6', text: 'Where does it come from?', name: 'h2' },
      { id: 'rdAK6TEAQqx', text: 'Where can I get some?', name: 'h4' },
    ]

    const result = createTableOfContents(content, { tags: 'h2, h4' })
    expect(result).toStrictEqual(expectedList)
  }


() => {
    const expectedList = [
      { id: 'hkY7o3DlYB2', text: 'What is Lorem Ipsum?' },
      { id: 'h4AL9B4qAV6', text: 'Where does it come from?' },
      { id: 'hBwwL6rm8B7', text: 'Why do we use it?' },
    ]

    const result = createTableOfContents(content, { dataForName: false })
    expect(result).toStrictEqual(expectedList)
  }


@Module({
  imports: [DbModule, UsersModule, BillsModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule { }


export default interface ITaskData {
    taskId?: any | null,
    taskName: string,
    taskDescription: string,
    startDate: string,
    endDate:string,
    isActive?:string
  }


function partOne(): number {
  let pathCount = 0;
  const paths: string[][] = [["start"]];
  while (paths.length) {
    const previous = paths.pop();
    const currentIndex = previous?.at(-1);
    const currentNodes = caves?.get(currentIndex!);
    if (!previous || !currentIndex || !currentNodes) continue;

    for (const node of currentNodes) {
      if (node === "end") {
        ++pathCount;
      } else if (node.toUpperCase() === node || !previous?.includes(node)) {
        paths.push(previous.concat(node));
      }
    }
  }

  return pathCount;
}


function partTwo(): number {
  let pathCount = 0;
  const paths: [string[], boolean][] = [[["start"], true]];

  const smallCaves: {
    [node: string]: number;
  } = {};

  while (paths.length) {
    const [previous, visitedSmall] = paths.pop()!;

    const currentIndex = previous.at(-1)!;
    const currentNodes = caves.get(currentIndex!)!;

    for (const node of currentNodes) {
      if (node === "end") {
        ++pathCount;
      } else if (node.toUpperCase() === node || !previous?.includes(node)) {
        paths.push([previous.concat(node), visitedSmall]);
      } else if (visitedSmall) {
        smallCaves[node] ||= 1;
        ++smallCaves[node];
        paths.push([previous.concat(node), false]);
      }
    }
  }

  return pathCount;
}


({
  minimumPercent = 0,
  percent,
  pattern: Pattern,
  bordered,
  size = 'small',
  variant = 'blue',
}) => {
  return (
    <ProgressBarWrapper
      aria-live="polite"
      border={bordered ? 'bordered' : 'basic'}
      size={size}
      variant={variant}
      backgroundOverride={Pattern ? 'pattern' : 'none'}
    >
      <Text as="label" screenreader>{`Progress: ${percent}%`}


export type ProgressBarProps = {
  className?: string;

  /**
   * Whether to increase size and display the percentage as text.
   */
  size?: 'small' | 'medium' | 'large' | 'xl';

  /**
   * Minimum amount of the bar to fill in visually.
   */
  minimumPercent?: number;

  /**
   * How much of the bar to fill in, as a number in [0, 100].
   */
  percent: number;

  /**
   * Base variant display themes.
   */
  variant: 'blue' | 'yellow' | 'dark' | 'light';

  /**
   * Base variant display themes.
   */
  bordered?: boolean;

  /**
   * Pattern component to use as a background.
   */
  pattern?: React.ComponentType<PatternProps>;
};


type ProgressBarElementProps = Pick<ProgressBarProps, 'variant' | 'size'>;


type ProgressBarElementWrapperProps = ProgressBarElementProps & {
  border: 'basic' | 'bordered';
  backgroundOverride: 'pattern' | 'none';
};


@Injectable()
export abstract class AnimalFacade {
  public abstract addAnimal(animal: string): void;
  public abstract resetAnimals(): void;
  public abstract getAnimals(): Observable<string[]>;
  public abstract getAddAnimalStatus(): Observable<StatusData>;
  public abstract getAnimalStateModel(): Observable<AnimalStateModel>;
}


public abstract addAnimal(animal: string): void;


public abstract resetAnimals(): void;


public abstract getAnimals(): Observable<string[]>;


public abstract getAddAnimalStatus(): Observable<StatusData>;


public abstract getAnimalStateModel(): Observable<AnimalStateModel>;


@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class GraphRoutingModule { }


(
    defaultData: PresenceData = {
      details: "Viewing an unsupported page",
      largeImageKey: "lg",
      startTimestamp: browsingStamp
    }
  ): void => {
    currentURL = new URL(document.location.href);
    currentPath = currentURL.pathname.replace(/^\/|\/$/g, "").split("/");
    presenceData = { ...defaultData };
  }


(urlParam: string): string => {
    return currentURL.searchParams.get(urlParam);
  }