text:
package de.oliver_heger.linedj.radio

import java.util.concurrent.atomic.AtomicInteger

import de.oliver_heger.linedj.player.engine.facade.RadioPlayer
import de.oliver_heger.linedj.player.engine.interval.IntervalQueries
import de.oliver_heger.linedj.player.engine.{RadioSource, RadioSourceErrorEvent}
import de.oliver_heger.linedj.radio.ErrorHandlingStrategy.{PlayerAction, State}
import net.sf.jguiraffe.gui.app.ApplicationContext
import net.sf.jguiraffe.gui.builder.action.{ActionStore, FormAction}
import net.sf.jguiraffe.gui.builder.components.WidgetHandler
import net.sf.jguiraffe.gui.builder.components.model.{ListComponentHandler, ListModel, StaticTextHandler}
import net.sf.jguiraffe.gui.builder.event.FormChangeEvent
import net.sf.jguiraffe.gui.builder.window.WindowEvent
import net.sf.jguiraffe.resources.Message
import org.apache.commons.configuration.{Configuration, HierarchicalConfiguration, PropertiesConfiguration}
import org.mockito.ArgumentMatchers.{eq => argEq, _}
import org.mockito.{ArgumentCaptor, Mockito}
import org.mockito.Mockito._
import org.mockito.invocation.InvocationOnMock
import org.mockito.stubbing.Answer
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.scalatestplus.mockito.MockitoSugar

import scala.concurrent.duration._

object RadioControllerSpec {
  /** Prefix for a radio source name. */
  private val RadioSourceName = "Radio_"

  /** Prefix for a radio source URI. */
  private val RadioSourceURI = "http://rad.io/"

  /** A text resource for the status line. */
  private val StatusText = "Text for the status line"

  /** The number of entries in the combo box. */
  private val ComboSize = 3

  /** The name of the start playback action. */
  private val StartPlaybackAction = "startPlaybackAction"

  /** The name of the stop playback action. */
  private val StopPlaybackAction = "stopPlaybackAction"

  /** A list with the names of the actions managed by the controller. */
  private val ActionNames = List(StartPlaybackAction, StopPlaybackAction)

  /** The recovery time in the player configuration (in seconds). */
  private val RecoveryTime = 300L

  /** The minimum number of failed sources to recover from. */
  private val MinFailedSources = 3

  /**
    * A data class storing information about radio sources passed to the mock
    * player's ''playSource()'' function.
    *
    * @param source      the radio source that was played
    * @param makeCurrent the make current flag
    * @param reset       the reset flag
    * @param delay       the delay
    */
  private case class RadioSourcePlayback(source: RadioSource,
                                         makeCurrent: Boolean,
                                         reset: Boolean,
                                         delay: FiniteDuration)

  /**
    * Generates the name for the source with the given index.
    *
    * @param idx the index
    * @return the name for this radio source
    */
  private def sourceName(idx: Int): String = RadioSourceName + idx

  /**
    * Generates a radio source object based on the given index.
    *
    * @param idx the index
    * @return the radio source for this index
    */
  private def radioSource(idx: Int): RadioSource =
    RadioSource(RadioSourceURI + idx)

  /**
    * Creates a configuration with settings for recovery.
    *
    * @return the configuration
    */
  private def createRecoveryConfiguration(): Configuration = {
    val config = new HierarchicalConfiguration
    config.addProperty("radio.error.recovery.time", RecoveryTime)
    config.addProperty("radio.error.recovery.minFailedSources", MinFailedSources)
    config
  }

  /**
    * Creates an error state with the given number of dysfunctional sources and
    * the given active source.
    *
    * @param srcCount  the number of dysfunctional sources
    * @param activeSrc the active radio source
    * @return the state
    */
  private def createStateWithErrorSources(srcCount: Int, activeSrc: RadioSource): ErrorHandlingStrategy
  .State = {
    val errorList = (1 to srcCount).map(i => radioSource(i)).toSet
    ErrorHandlingStrategy.NoError.copy(errorList = errorList, activeSource = Option(activeSrc))
  }
}

/**
  * Test class for ''RadioController''.
  */
class RadioControllerSpec extends AnyFlatSpec with Matchers with MockitoSugar {

  import RadioControllerSpec._

  /**
    * Creates a test window event of the specified type.
    *
    * @return the test window event
    */
  private def event(): WindowEvent = mock[WindowEvent]

  /**
    * Creates a mock source configuration that contains the given number of
    * radio sources. All sources are defined with their name and URI.
    *
    * @param count the number of radio sources
    * @return the configuration defining the number of radio sources
    */
  private def createSourceConfiguration(count: Int): RadioSourceConfig = {
    val sources = (1 to count) map (i => (sourceName(i), radioSource(i)))
    createSourceConfiguration(sources)
  }

  /**
    * Creates a configuration that contains the specified radio sources.
    *
    * @param sources a list with the sources to be contained
    * @return the configuration with these radio sources
    */
  private def createSourceConfiguration(sources: Seq[(String, RadioSource)]): RadioSourceConfig = {
    val config = mock[RadioSourceConfig]
    when(config.sources).thenReturn(sources)
    when(config.ranking(any(classOf[RadioSource]))).thenAnswer((invocation: InvocationOnMock) => {
      val src = invocation.getArguments.head.asInstanceOf[RadioSource]
      val index = src.uri.substring(RadioSourceURI.length)
      index.toInt
    })
    config
  }

  "A RadioController" should "create a default source config factory" in {
    val helper = new RadioControllerTestHelper
    val config = new HierarchicalConfiguration
    config.addProperty("radio.sources.source.name", RadioSourceName)
    config.addProperty("radio.sources.source.uri", RadioSourceURI)

    val ctrl = new RadioController(helper.player, config, helper.applicationContext,
      helper.actionStore, helper.comboHandler, helper.statusHandler, helper.playbackTimeHandler,
      helper.errorIndicator, helper.errorHandlingStrategy)
    val srcConfig = ctrl.configFactory(config)
    srcConfig.sources should have size 1
    srcConfig.sources.head._1 should be(RadioSourceName)
    srcConfig.sources.head._2.uri should be(RadioSourceURI)
  }

  it should "add radio sources to the combo box" in {
    val helper = new RadioControllerTestHelper
    helper.createInitializedController(createSourceConfiguration(4))

    helper.verifySourcesAddedToCombo(1, 2, 3, 4).verifySelectedSource(1)
      .verifyNoMoreInteractionWithCombo()
  }

  it should "hide the error indicator initially" in {
    val helper = new RadioControllerTestHelper
    helper.createInitializedController(createSourceConfiguration(1),
      resetErrorIndicator = false)

    verify(helper.errorIndicator).setVisible(false)
  }

  it should "handle missing source configurations correctly" in {
    val helper = new RadioControllerTestHelper

    helper.createInitializedController(RadioSourceConfig(new HierarchicalConfiguration))
    verify(helper.player).initSourceExclusions(any(), any())
    helper.verifySourcesAddedToCombo()
      .verifyNoMoreInteractionWithCombo()
      .verifyNoMorePlayerInteraction()
  }

  it should "disable playback actions if there are no sources" in {
    val helper = new RadioControllerTestHelper
    helper.createInitializedController(RadioSourceConfig(new HierarchicalConfiguration))

    helper.verifyAction(StartPlaybackAction, enabled = false)
      .verifyAction(StopPlaybackAction, enabled = false)
  }

  it should "set action states correctly if there are sources" in {
    val helper = new RadioControllerTestHelper
    helper.createInitializedController(createSourceConfiguration(1))

    helper.verifyAction(StartPlaybackAction, enabled = false)
      .verifyAction(StopPlaybackAction, enabled = true)
  }

  it should "start playback with the first source if not otherwise specified" in {
    val helper = new RadioControllerTestHelper
    helper.createInitializedController(createSourceConfiguration(1))

    helper.verifyInitialStartPlayback(radioSource(1))
  }

  it should "start playback with the stored source from the configuration" in {
    val srcConfig = createSourceConfiguration(4)
    val config = new HierarchicalConfiguration
    config.addProperty("radio.current", sourceName(2))
    val helper = new RadioControllerTestHelper
    helper.createInitializedController(srcConfig, config)

    helper.verifySelectedSource(2)
      .verifyInitialStartPlayback(radioSource(2))
  }

  it should "start playback with a configured delay" in {
    val helper = new RadioControllerTestHelper
    val config = new HierarchicalConfiguration
    val Delay = 1.second
    config.addProperty("radio.initialDelay", Delay.toMillis)
    helper.createInitializedController(createSourceConfiguration(1), config)

    helper.verifyInitialStartPlayback(radioSource(1), delay = Delay)
  }

  it should "store the current source in the configuration after startup" in {
    val helper = new RadioControllerTestHelper
    val srcConfig = createSourceConfiguration(1)
    val config = new HierarchicalConfiguration
    helper.createInitializedController(srcConfig, config)

    config getString "radio.current" should be(sourceName(1))
  }

  it should "ignore the stored source if it cannot be resolved" in {
    val srcConfig = createSourceConfiguration(3)
    val config = new HierarchicalConfiguration
    config.addProperty("radio.current", sourceName(4))
    val helper = new RadioControllerTestHelper
    helper.createInitializedController(srcConfig, config)

    helper.verifyInitialStartPlayback(radioSource(1))
  }

  it should "react on changes in the radio sources selection while playback is not active" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createController(createSourceConfiguration(0))
    val src = radioSource(2)
    doReturn(src).when(helper.comboHandler).getData

    ctrl elementChanged mock[FormChangeEvent]
    helper.verifySwitchSource(radioSource(2))
      .verifyNoMorePlayerInteraction()
  }

  it should "react on changes in the radio sources selection while playback is active" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(2))
    val src = radioSource(2)
    doReturn(src).when(helper.comboHandler).getData

    ctrl elementChanged mock[FormChangeEvent]
    verify(helper.player).playSource(src, makeCurrent = true)
  }

  it should "update the current source in the config after a change in the combo selection" in {
    val srcConfig = createSourceConfiguration(3)
    val config = new HierarchicalConfiguration
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(srcConfig, config)
    val src = radioSource(2)
    doReturn(src).when(helper.comboHandler).getData

    ctrl elementChanged mock[FormChangeEvent]
    config getString "radio.current" should be(sourceName(2))
  }

  it should "handle an empty selection in the sources combo box" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createController(createSourceConfiguration(0))
    doReturn(null).when(helper.comboHandler).getData

    ctrl elementChanged mock[FormChangeEvent]
    helper.verifyNoMorePlayerInteraction()
  }

  it should "ignore change events while populating the sources combo box" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createController(createSourceConfiguration(4))
    doAnswer((_: InvocationOnMock) => {
      ctrl elementChanged mock[FormChangeEvent]
      null
    }).when(helper.comboHandler).addItem(anyInt(), any(), any())
    doReturn(radioSource(3)).when(helper.comboHandler).getData

    ctrl windowOpened event()
    helper.verifyInitialStartPlayback(radioSource(1))
    verify(helper.player, never()).playSource(argEq(radioSource(2)), anyBoolean(), anyBoolean(), any())
  }

  it should "reset the sources update flag after the update" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(4))
    helper.verifyInitialStartPlayback(radioSource(1))
    val selectedSource = radioSource(2)

    doReturn(selectedSource).when(helper.comboHandler).getData
    ctrl.elementChanged(null)
    verify(helper.player).playSource(selectedSource, makeCurrent = true)
  }

  it should "send exclusion data to the radio player" in {
    val srcConfig = createSourceConfiguration(2)
    val exclusions = Map(radioSource(1) -> List(IntervalQueries.hours(0, 8)),
      radioSource(2) -> List(IntervalQueries.hours(9, 12)))
    when(srcConfig.exclusions).thenReturn(exclusions)
    val helper = new RadioControllerTestHelper

    helper.createInitializedController(srcConfig)
    val captRanking = ArgumentCaptor.forClass(classOf[RadioSource.Ranking])
    verify(helper.player).initSourceExclusions(argEq(exclusions), captRanking.capture())
    val ranking = captRanking.getValue
    ranking(radioSource(2)) should be(2)
    ranking(radioSource(8)) should be(8)
  }

  it should "update the status text when the current source is played" in {
    val helper = new RadioControllerTestHelper().expectResource("txt_status_playback")
    val ctrl = helper.createInitializedController(createSourceConfiguration(1))

    ctrl radioSourcePlaybackStarted radioSource(1)
    verify(helper.statusHandler).setText(StatusText)
  }

  it should "update the status text if a replacement source is played" in {
    val replaceSrc = radioSource(2)
    val msg = new Message(null, "txt_status_replacement", sourceName(2))
    val helper = new RadioControllerTestHelper().expectMessageResource(msg)
    val ctrl = helper.createInitializedController(createSourceConfiguration(2))

    ctrl radioSourcePlaybackStarted replaceSrc
    verify(helper.statusHandler).setText(StatusText)
  }

  it should "update the status text if an unknown replacement source is played" in {
    val replaceSrc = radioSource(2)
    val msg = new Message(null, "txt_status_replacement", replaceSrc.uri)
    val helper = new RadioControllerTestHelper().expectMessageResource(msg)
    val ctrl = helper.createInitializedController(createSourceConfiguration(1))

    ctrl radioSourcePlaybackStarted replaceSrc
    verify(helper.statusHandler).setText(StatusText)
  }

  it should "update the playback time" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(1))

    ctrl playbackTimeProgress 65
    verify(helper.playbackTimeHandler).setText("1:05")
  }

  /**
    * Helper method for testing that an event is ignored. It is only checked
    * that the event is not touched.
    *
    * @param f a function that invokes a controller method with an event
    */
  private def checkIgnoredEvent(f: (RadioController, WindowEvent) => Unit): Unit = {
    val ev = event()
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createController(createSourceConfiguration(0))
    f(ctrl, ev)
    verifyNoInteractions(ev)
  }

  it should "ignore de-iconified events" in {
    checkIgnoredEvent(_.windowDeiconified(_))
  }

  it should "ignore closing events" in {
    checkIgnoredEvent(_.windowClosing(_))
  }

  it should "ignore closed events" in {
    checkIgnoredEvent(_.windowClosed(_))
  }

  it should "ignore activated events" in {
    checkIgnoredEvent(_.windowActivated(_))
  }

  it should "ignore deactivated events" in {
    checkIgnoredEvent(_.windowDeactivated(_))
  }

  it should "ignore iconified events" in {
    checkIgnoredEvent(_.windowIconified(_))
  }

  it should "allow stopping playback" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createController(createSourceConfiguration(0))

    ctrl.stopPlayback()
    helper.verifyStopPlayback()
      .verifyAction(StartPlaybackAction, enabled = true)
      .verifyAction(StopPlaybackAction, enabled = false)
  }

  it should "allow restarting playback" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(1))
    ctrl.stopPlayback()

    ctrl.startPlayback()
    verify(helper.player).playSource(radioSource(1), makeCurrent = false)
    helper.verifyAction(StartPlaybackAction, enabled = false, count = 2)
      .verifyAction(StopPlaybackAction, enabled = true, count = 2)
  }

  it should "set the playback active flag when restarting playback" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(2))
    ctrl.stopPlayback()
    ctrl.startPlayback()
    val src = radioSource(2)
    doReturn(src).when(helper.comboHandler).getData

    ctrl elementChanged mock[FormChangeEvent]
    val playback = helper.singlePlaybackFor(src)
    playback.makeCurrent shouldBe true
  }

  it should "pass a correct configuration to the error handling strategy" in {
    val playerConfig = new PropertiesConfiguration
    playerConfig.addProperty("radio.error.maxRetries", 10)
    val srcConfig = createSourceConfiguration(4)
    val helper = new RadioControllerTestHelper
    val (answer, _) = helper.expectErrorStrategyCall()
    val ctrl = helper.createInitializedController(srcConfig, playerConfig,
      playbackSrcIdx = 1)

    ctrl playbackError RadioSourceErrorEvent(radioSource(1))
    answer.config.sourcesConfig should be(srcConfig)
    answer.config.maxRetries should be(10)
  }

  it should "invoke the error handling strategy correctly" in {
    val srcConfig = createSourceConfiguration(8)
    val helper = new RadioControllerTestHelper
    val (answer, _) = helper.expectErrorStrategyCall()
    val error = RadioSourceErrorEvent(srcConfig.sources(2)._2)
    val ctrl = helper.createInitializedController(srcConfig, playbackSrcIdx = 2)

    ctrl playbackError error
    answer.errorSource should be(error.source)
    answer.currentSource should be(srcConfig.sources.head._2)
    answer.previousState should be(ErrorHandlingStrategy.NoError)
  }

  it should "invoke the player action from the error handling strategy" in {
    val helper = new RadioControllerTestHelper
    val (_, counter) = helper.expectErrorStrategyCall()
    val ctrl = helper.createInitializedController(createSourceConfiguration(2),
      playbackSrcIdx = 1)

    ctrl playbackError RadioSourceErrorEvent(radioSource(1))
    counter.get() should be(1)
  }

  it should "not handle a playback error if there is no playback source" in {
    val helper = new RadioControllerTestHelper
    val (_, counter) = helper.expectErrorStrategyCall()
    val ctrl = helper.createInitializedController(createSourceConfiguration(2))

    ctrl playbackError RadioSourceErrorEvent(radioSource(1))
    counter.get() should be(0)
  }

  it should "display the error indicator when a playback error was detected" in {
    val helper = new RadioControllerTestHelper
    helper.expectErrorStrategyCall()
    val ctrl = helper.createInitializedController(createSourceConfiguration(2),
      playbackSrcIdx = 1)

    ctrl playbackError RadioSourceErrorEvent(radioSource(1))
    verify(helper.errorIndicator).setVisible(true)
  }

  it should "record the next error state" in {
    val nextState = ErrorHandlingStrategy.NoError.copy(retryMillis = 10000)
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(8),
      playbackSrcIdx = 1)
    helper.injectErrorState(ctrl, nextState, 3)

    val (answer, _) = helper.expectErrorStrategyCall()
    ctrl radioSourcePlaybackStarted radioSource(3)
    ctrl playbackError RadioSourceErrorEvent(radioSource(3))
    answer.previousState should be(nextState)
  }

  it should "clear the error state when the user selects another source" in {
    val nextState = ErrorHandlingStrategy.NoError.copy(retryMillis = 15000)
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(8),
      playbackSrcIdx = 1)
    helper.injectErrorState(ctrl, nextState, 1)

    doReturn(radioSource(2)).when(helper.comboHandler).getData
    ctrl elementChanged mock[FormChangeEvent]
    verify(helper.errorIndicator).setVisible(false)
    val (answer, _) = helper.expectErrorStrategyCall()
    ctrl radioSourcePlaybackStarted radioSource(1)
    ctrl playbackError RadioSourceErrorEvent(radioSource(1))
    answer.previousState should be(ErrorHandlingStrategy.NoError)
  }

  it should "recover from an error after the configured time" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(8),
      createRecoveryConfiguration(), playbackSrcIdx = 7)
    helper.injectErrorState(ctrl, createStateWithErrorSources(MinFailedSources, radioSource(7)), 1)

    ctrl playbackTimeProgress RecoveryTime
    verify(helper.player).playSource(radioSource(1), makeCurrent = false)
    verify(helper.errorIndicator).setVisible(false)
    val (answer, _) = helper.expectErrorStrategyCall()
    ctrl radioSourcePlaybackStarted radioSource(2)
    ctrl playbackError RadioSourceErrorEvent(radioSource(2))
    answer.previousState should be(ErrorHandlingStrategy.NoError)
  }

  it should "not change the source on recovery if it is already played" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(4),
      createRecoveryConfiguration(), playbackSrcIdx = 1)
    helper.injectErrorState(ctrl, createStateWithErrorSources(MinFailedSources + 1,
      radioSource(1)), 1)

    ctrl playbackTimeProgress RecoveryTime
    verify(helper.errorIndicator).setVisible(false)
    helper.verifyNoMorePlayerInteraction()
  }

  it should "not recover from error if not in error state" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(2),
      createRecoveryConfiguration())

    ctrl playbackTimeProgress RecoveryTime
    helper.verifyNoRecovery()
  }

  it should "not recover if the recovery time is not yet reached" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(2),
      createRecoveryConfiguration())
    helper.injectErrorState(ctrl, createStateWithErrorSources(MinFailedSources,
      radioSource(1)), 1)

    ctrl playbackTimeProgress RecoveryTime - 1
    helper.verifyNoRecovery()
  }

  it should "not recover if the number of dysfunctional sources is too small" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(2),
      createRecoveryConfiguration())
    helper.injectErrorState(ctrl, createStateWithErrorSources(MinFailedSources - 1,
      radioSource(1)), 1)

    ctrl playbackTimeProgress RecoveryTime
    helper.verifyNoRecovery()
  }

  it should "use default values for recovery settings" in {
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(1))

    ctrl.errorRecoveryTime should be(600)
    ctrl.minFailedSourcesForRecovery should be(1)
  }

  it should "handle an event about a failed playback context creation" in {
    val helper = new RadioControllerTestHelper
    val (_, counter) = helper.expectErrorStrategyCall()
    val ctrl = helper.createInitializedController(createSourceConfiguration(2),
      playbackSrcIdx = 1)

    ctrl.playbackContextCreationFailed()
    counter.get() should be(1)
  }

  it should "not handle a failed playback context creation after a playback error" in {
    val srcConfig = createSourceConfiguration(8)
    val helper = new RadioControllerTestHelper
    val (_, counter) = helper.expectErrorStrategyCall()
    val errorSource = radioSource(1)
    val ctrl = helper.createInitializedController(srcConfig)
    ctrl radioSourcePlaybackStarted errorSource
    ctrl playbackError RadioSourceErrorEvent(errorSource)

    ctrl.playbackContextCreationFailed()
    counter.get() should be(1)
  }

  it should "record a replacement source and start playback of it later" in {
    val repSrc = radioSource(2)
    val msg = new Message(null, "txt_status_replacement", sourceName(2))
    val helper = new RadioControllerTestHelper
    helper.expectMessageResource(msg)
    val ctrl = helper.createInitializedController(createSourceConfiguration(4))
    ctrl.stopPlayback()

    ctrl replacementSourceStarts repSrc
    helper.playbacksFor(repSrc) should have size 0
    ctrl.startPlayback()
    val playback = helper.singlePlaybackFor(repSrc)
    playback.makeCurrent shouldBe false
    verify(helper.statusHandler).setText(StatusText)
  }

  it should "directly switch to a replacement source if playback is enabled" in {
    val repSrc = radioSource(3)
    val msg = new Message(null, "txt_status_replacement", sourceName(3))
    val helper = new RadioControllerTestHelper
    helper.expectMessageResource(msg)
    val ctrl = helper.createInitializedController(createSourceConfiguration(4))

    ctrl replacementSourceStarts repSrc
    helper.singlePlaybackFor(repSrc).makeCurrent shouldBe false
    verify(helper.statusHandler, never()).setText(anyString())
  }

  it should "handle an end of the replacement source if playback is not active" in {
    val repSrc = radioSource(2)
    val helper = new RadioControllerTestHelper
    helper.expectResource("txt_status_playback")
    val ctrl = helper.createInitializedController(createSourceConfiguration(4))
    ctrl.stopPlayback()

    ctrl replacementSourceStarts repSrc
    ctrl.replacementSourceEnds()
    ctrl.startPlayback()
    helper.playbacksFor(repSrc) should have size 0
    val pb = helper.playbacksFor(radioSource(1))
    pb should have size 2
    pb.head.makeCurrent shouldBe false
    verify(helper.statusHandler).setText(StatusText)
  }

  it should "handle an end of the replacement source if playback is active" in {
    val repSrc = radioSource(3)
    val helper = new RadioControllerTestHelper
    val ctrl = helper.createInitializedController(createSourceConfiguration(4))

    ctrl replacementSourceStarts repSrc
    ctrl.replacementSourceEnds()
    helper.singlePlaybackFor(repSrc).makeCurrent shouldBe false
    val pb = helper.playbacksFor(radioSource(1))
    pb should have size 2
    pb.head.makeCurrent shouldBe false
    verifyNoInteractions(helper.statusHandler)
  }

  /**
    * A helper class managing the dependencies of the test object.
    */
  private class RadioControllerTestHelper {
    /** Stores the sources that have been played. */
    var playedSources = List.empty[RadioSourcePlayback]

    /** Mock for the radio player. */
    val player: RadioPlayer = createRadioPlayerMock()

    /** Mock for the application context. */
    val applicationContext: ApplicationContext = mock[ApplicationContext]

    /** Mock for the combo box handler. */
    val comboHandler: ListComponentHandler = createComboHandlerMock()

    /** Mock for the status line handler. */
    val statusHandler: StaticTextHandler = mock[StaticTextHandler]

    /** Mock for the handler for the playback time. */
    val playbackTimeHandler: StaticTextHandler = mock[StaticTextHandler]

    /** Mock for the error indicator control. */
    val errorIndicator: WidgetHandler = mock[WidgetHandler]

    /** Mock for the error handling strategy. */
    val errorHandlingStrategy: ErrorHandlingStrategy = mock[ErrorHandlingStrategy]

    /** A map with mock actions. */
    private val actions = createActionMap()

    /** Mock for the action store. */
    val actionStore: ActionStore = createActionStore(actions)

    /**
      * Creates a test instance of a radio controller.
      *
      * @param srcConfig     the configuration for the radio sources
      * @param configuration the configuration
      * @return the test instance
      */
    def createController(srcConfig: RadioSourceConfig,
                         configuration: Configuration = new HierarchicalConfiguration):
    RadioController =
      new RadioController(player, configuration, applicationContext, actionStore, comboHandler,
        statusHandler, playbackTimeHandler, errorIndicator, errorHandlingStrategy, c => {
          c should be(configuration)
          srcConfig
        })

    /**
      * Creates a radio controller test instance and initializes it by sending
      * it a window opened event.
      *
      * @param srcConfig           the configuration for the radio sources
      * @param configuration       the configuration
      * @param resetErrorIndicator flag whether the error indicator mock
      *                            should be reset (the indicator is hidden
      *                            at initialization time)
      * @param playbackSrcIdx      an index for the current source to be set;
      *                            negative for none
      * @return the test instance
      */
    def createInitializedController(srcConfig: RadioSourceConfig,
                                    configuration: Configuration = new HierarchicalConfiguration,
                                    resetErrorIndicator: Boolean = true,
                                    playbackSrcIdx: Int = -1)
    : RadioController = {
      val ctrl = createController(srcConfig, configuration)
      ctrl windowOpened event()
      if (playbackSrcIdx >= 0) {
        ctrl radioSourcePlaybackStarted radioSource(playbackSrcIdx)
      }
      if (resetErrorIndicator) {
        reset(errorIndicator)
      }
      ctrl
    }

    /**
      * Verifies that the provided sources have been added to the combo box (in
      * this order). Also checks that existing entries were removed before.
      *
      * @param expSources the expected sources to be added
      * @return this test helper
      */
    def verifySourcesAddedToCombo(expSources: Int*): RadioControllerTestHelper = {
      val verInOrder = Mockito.inOrder(comboHandler)
      verInOrder.verify(comboHandler).getListModel
      (1 to ComboSize).reverse foreach { i =>
        verInOrder.verify(comboHandler).removeItem(i - 1)
      }
      expSources.zipWithIndex foreach { e =>
        verInOrder.verify(comboHandler).addItem(e._2, sourceName(e._1), radioSource(e._1))
      }
      this
    }

    /**
      * Verifies that the specified radio source was set as selected element in
      * the radio sources combo box.
      *
      * @param src the radio source
      * @return this test helper
      */
    def verifySelectedSource(src: RadioSource): RadioControllerTestHelper = {
      verify(comboHandler).setData(src)
      this
    }

    /**
      * Verifies that the radio source with the specified index was set as
      * selected element in the radio sources combo box.
      *
      * @param idx the index of the radio source
      * @return this test helper
      */
    def verifySelectedSource(idx: Int): RadioControllerTestHelper =
      verifySelectedSource(radioSource(idx))

    /**
      * Checks that there was no further interaction with the combo box for
      * radio sources.
      *
      * @return this test helper
      */
    def verifyNoMoreInteractionWithCombo(): RadioControllerTestHelper = {
      verifyNoMoreInteractions(comboHandler)
      this
    }

    /**
      * Verifies whether the correct state for the specified action has been
      * set.
      *
      * @param name    the name of the action
      * @param enabled the expected state
      * @param count   the number of expected invocations
      * @return this test helper
      */
    def verifyAction(name: String, enabled: Boolean, count: Int = 1): RadioControllerTestHelper = {
      verify(actions(name), times(count)).setEnabled(enabled)
      this
    }

    /**
      * Verifies that the player was triggered to switch to the specified
      * source.
      *
      * @param src the source
      * @return this test helper
      */
    def verifySwitchSource(src: RadioSource): RadioControllerTestHelper = {
      verify(player).makeToCurrentSource(src)
      this
    }

    /**
      * Verifies that playback has been started initially after the startup of
      * the controller.
      *
      * @param src   the source to be played
      * @param delay the expected delay
      * @return this test helper
      */
    def verifyInitialStartPlayback(src: RadioSource,
                                   delay: FiniteDuration = RadioController.DefaultInitialDelay.millis):
    RadioControllerTestHelper = {
      val playback = playbacksFor(src)
        .find(src => src.makeCurrent && !src.reset && src.delay == delay)
      playback.isDefined shouldBe true
      this
    }

    /**
      * Verifies that playback was stopped.
      *
      * @return this test helper
      */
    def verifyStopPlayback(): RadioControllerTestHelper = {
      verify(player).stopPlayback()
      this
    }

    /**
      * Verifies that there were no further interactions with the radio player.
      *
      * @return this test helper
      */
    def verifyNoMorePlayerInteraction(): RadioControllerTestHelper = {
      verifyNoMoreInteractions(player)
      this
    }

    /**
      * Prepares the mock application context for a resource request based on a
      * resource key.
      *
      * @param key  the resource key
      * @param text the text to be returned
      * @return this test helper
      */
    def expectResource(key: AnyRef, text: String = StatusText): RadioControllerTestHelper = {
      when(applicationContext.getResourceText(key)).thenReturn(text)
      this
    }

    /**
      * Prepares the mock application context for a resource request based on a
      * ''Message'' object.
      *
      * @param msg  the expected message object
      * @param text the text to be returned
      * @return this test helper
      */
    def expectMessageResource(msg: Message, text: String = StatusText): RadioControllerTestHelper = {
      when(applicationContext.getResourceText(msg)).thenReturn(text)
      this
    }

    /**
      * Prepares the mock error handling strategy to expect an invocation. An
      * answer is set that records the invocation. Also, a player action is
      * created that records its invocation.
      *
      * @param nextState the next state to be returned
      * @return the mock answer for the strategy and a counter for action calls
      */
    def expectErrorStrategyCall(nextState: ErrorHandlingStrategy.State =
                                ErrorHandlingStrategy.NoError):
    (ErrorStrategyAnswer, AtomicInteger) = {
      val counter = new AtomicInteger
      val action: ErrorHandlingStrategy.PlayerAction = p => {
        p should be(player)
        counter.incrementAndGet()
      }
      val answer = new ErrorStrategyAnswer(action, nextState)
      when(errorHandlingStrategy.handleError(any[ErrorHandlingStrategy.Config],
        any[ErrorHandlingStrategy.State], any[RadioSourceErrorEvent], any[RadioSource]))
        .thenAnswer(answer)
      (answer, counter)
    }

    /**
      * Invokes the given test controller to bring it into a specific error
      * state.
      *
      * @param ctrl  the controller
      * @param state the error state
      * @param idx   the index of the source for the error event
      */
    def injectErrorState(ctrl: RadioController, state: ErrorHandlingStrategy.State,
                         idx: Int): (ErrorStrategyAnswer, AtomicInteger) = {
      val t = expectErrorStrategyCall(state)
      ctrl playbackError RadioSourceErrorEvent(radioSource(idx))
      reset(errorIndicator, errorHandlingStrategy, player)
      t
    }

    /**
      * Verifies that no error recovery has been done. This is done via the
      * error indicator mock.
      *
      * @return this test helper
      */
    def verifyNoRecovery(): RadioControllerTestHelper = {
      verify(errorIndicator, never()).setVisible(false)
      this
    }

    /**
      * Returns information about playbacks of the source specified.
      *
      * @param source the source in question
      * @return a list with playback operations for this source
      */
    def playbacksFor(source: RadioSource): List[RadioSourcePlayback] =
      playedSources.filter(_.source == source)

    /**
      * Verifies that there was a single playback of the given source and
      * returns information about it.
      *
      * @param source the source in question
      * @return the information about the playback of this source
      */
    def singlePlaybackFor(source: RadioSource): RadioSourcePlayback = {
      val playbacks = playbacksFor(source)
      playbacks should have size 1
      playbacks.head
    }

    /**
      * Creates a mock for the combo box handler.
      *
      * @return the mock combo box handler
      */
    private def createComboHandlerMock(): ListComponentHandler = {
      val handler = mock[ListComponentHandler]
      val model = mock[ListModel]
      when(handler.getListModel).thenReturn(model)
      when(model.size()).thenReturn(ComboSize)
      handler
    }

    /**
      * Creates mock actions for the actions managed by the controller and
      * returns a map for accessing them by name.
      *
      * @return the map with actions
      */
    private def createActionMap(): Map[String, FormAction] =
      ActionNames.map((_, mock[FormAction])).toMap

    /**
      * Creates a mock for the action store that manages the specified actions.
      *
      * @param actionMap a map with supported actions
      * @return the mock action store
      */
    private def createActionStore(actionMap: Map[String, FormAction]): ActionStore = {
      val store = mock[ActionStore]
      actionMap foreach { e =>
        when(store.getAction(e._1)).thenReturn(e._2)
      }
      store
    }

    /**
      * Creates the mock radio player and configures it to store information
      * about radio sources that have been played. Obviously, Mockito has
      * problems with Scala's default parameters; it cannot correctly resolve
      * radio sources in its ''verify()'' methods. Therefore, the sources are
      * stored and evaluated manually.
      *
      * @return the mock radio player
      */
    private def createRadioPlayerMock(): RadioPlayer = {
      val player = mock[RadioPlayer]
      when(player.playSource(any(), anyBoolean(), anyBoolean(), any()))
        .thenAnswer((invocation: InvocationOnMock) => {
          val playback = RadioSourcePlayback(invocation.getArgument(0, classOf[RadioSource]),
            invocation.getArgument(1, classOf[java.lang.Boolean]),
            invocation.getArgument(2, classOf[java.lang.Boolean]),
            invocation.getArgument(3, classOf[FiniteDuration]))
          playedSources = playback :: playedSources
        })
      player
    }
  }

  /**
    * An answer class to check an invocation of the error handling strategy.
    *
    * @param action the action to be returned
    * @param state  the next state to be returned
    */
  private class ErrorStrategyAnswer(action: ErrorHandlingStrategy.PlayerAction,
                                    state: ErrorHandlingStrategy.State)
    extends Answer[(ErrorHandlingStrategy.PlayerAction, ErrorHandlingStrategy.State)] {
    /** The config passed to the strategy. */
    var config: ErrorHandlingStrategy.Config = _

    /** The previous state passed to the strategy. */
    var previousState: ErrorHandlingStrategy.State = _

    /** The radio source causing an error. */
    var errorSource: RadioSource = _

    /** The current source. */
    var currentSource: RadioSource = _

    override def answer(invocation: InvocationOnMock): (PlayerAction, State) = {
      config = invocation.getArguments.head.asInstanceOf[ErrorHandlingStrategy.Config]
      previousState = invocation.getArguments()(1).asInstanceOf[ErrorHandlingStrategy.State]
      errorSource = invocation.getArguments()(2).asInstanceOf[RadioSourceErrorEvent].source
      currentSource = invocation.getArguments()(3).asInstanceOf[RadioSource]
      (action, state)
    }
  }

}


text:
Insights • Market Updates
Putting Our Global Growth Surge Forecast in Perspective
Global GDP is poised for a growth spurt in 2021. Although our forecast suggests 5.7% growth for 2021, the fastest since 1973, there are important nuances that complicate the story. For one, we should not confuse economic momentum and breadth with completeness. Furthermore, even as global GDP returns to pre-crisis levels, labor market recovery will likely take a more protracted course.
Simona M Mocuta
Following a 3.4% contraction in 2020, the global economy is poised for a sharp rebound this year. We expect global real GDP growth (purchasing power parity-weighted) to hit 5.7% in 2021. If this materializes, it would mark the fastest expansion rate since 1973 (Figure 1).
Figure 1: Poised For the Best Global Growth Since 1973?
While the pace of vaccine deployment varies widely across countries, we believe these disparities will narrow substantially during the second half of the year as the frontrunners level off and the laggards catch up. This means, although a slow start to vaccinations will delay and likely handicap the recovery, it will not altogether preclude it. Therefore, we anticipate essentially all economies to participate in this upturn such that this global growth rebound will not only be fast but also broad. In some ways, this will be very reminiscent of the synchronized growth story of 2017, but in others, it will be quite different.
Same But Different
Indeed, we must not confuse momentum and breadth with completeness. For instance, only China has so far exceeded its peak pre-COVID-19 GDP – having done so in Q2 2020. The United States (US) and Australia are expected to cross that mark by mid-year, and Germany could reach it in the third quarter. But for many other economies this will not happen until late 2021 or, as in the case of Japan and others, until 2022. Thus, while in absolute growth terms this global rebound will look even better than that of 2017, the reality is much more subdued.
In this context, taking a two-year view should prove to be instructive. Between the fourth quarter of 2015 and the fourth quarter of 2017, for instance, China's economy grew by 14%, the US economy by 4.8% and Japan by 2.7%. Based on our forecasts, in the two years ending Q4 2021, China and the US will have grown by 9.0% and 3.1%, respectively, whereas Japan's GDP will have contracted by 1.9% (Figure 2). Context matters, and in 2021 in particular, it matters greatly. Beyond the two-year horizon, a permanent output loss due to the pandemic will be a long-lasting scar on the global economy.
Figure 2: 2017 and 2021 Growth Spurts in Perspective
Labor Market Evolves
There is another facet of the current recovery that warrants discussion, namely, the evolution of the labor market. Global GDP may return to pre-crisis levels this year or the next, but labor markets will take longer to complete that journey. Indeed, between the start of 2016 and the end of 2017, the aggregate unemployment levels in Eurozone, Japan, the US, the UK, Australia and Canada declined by about 5 million people. As we begin 2021, unemployment in these countries is up by 7.5 million compared with January 2020. To match the 2016-17 performance, we would need unemployment to drop by 12.5 million over the course of 2021, which is quite unlikely!
Figure 3: Labor Market Performance Far Weaker Now Than in 2017
Therefore, while quite impressive, this year's economic rebound will, by nearly all measures and for nearly all countries, represent an incomplete recovery from the severe COVID-19 induced recession. It is important to remember this since many equity markets are close to or have already made a full recovery to pre-pandemic highs.
The whole or any part of this work may not be reproduced, copied or transmitted or any of its contents disclosed to third parties without State Street Global Advisors' express written consent.
The views expressed in this material are the views of the Global Macro and Policy Research team through 05 April 2021 and are subject to change based on market and other conditions. This document contains certain statements that may be deemed forward looking statements. Please note that any such statements are not guarantees of any future performance and actual results or developments may differ materially from those projected.
The information provided does not constitute investment advice and it should not be relied on as such. It should not be considered a solicitation to buy or an offer to sell a security. It does not take into account any investor's particular investment objectives, strategies, tax status or investment horizon. You should consult your tax and financial advisor. All information is from State Street Global Advisors unless otherwise noted and has been obtained from sources believed to be reliable, but its accuracy is not guaranteed. There is no representation or warranty as to the current accuracy, reliability or completeness of, nor liability for, decisions based on such information and it should not be relied on as such.
Past performance is not a guarantee of future results. Investing involves risk including the risk of loss of principal.
The trademarks and service marks referenced herein are the property of their respective owners. Third party data providers make no warranties or representations of any kind relating to the accuracy, completeness or timeliness of the data and have no liability for damages of any kind relating to the use of such data.
For EMEA Distribution: The information contained in this communication is not a research recommendation or 'investment research' and is classified as a 'Marketing Communication' in accordance with the Markets in Financial Instruments Directive (2014/65/EU) or applicable Swiss regulation. This means that this marketing communication (a) has not been prepared in accordance with legal requirements designed to promote the independence of investment research (b) is not subject to any prohibition on dealing ahead of the dissemination of investment research.
State Street Global Advisors Worldwide Entities
© 2021 State Street Corporation – All rights reserved.
Tracking Code: 3533261.1.1.GBL.RTL
Expiration Date: 04.30.2022
Information Classification: General Access
This information is for informational purposes only, not to be construed as investment advice or a recommendation or offer to buy or sell any security. Investors should always obtain and read an up-to-date investment services description or prospectus before deciding whether to appoint an investment manager or to invest in a fund. Any views expressed herein are those of the author(s), are based on available information, and are subject to change without notice. Individual portfolio management teams may hold different views and may make different investment decisions for different clients. There are no guarantees regarding the achievement of investment objectives, target returns, portfolio construction, allocations or measurements such as alpha, tracking error, stock weightings and other information ratios. The views and strategies described may not be suitable for all investors. SSGA does not provide tax or legal advice. Prospective investors should consult with a tax or legal advisor before making any investment decision. Investing entails risks and there can be no assurance that SSGA will achieve profits or avoid incurring losses.
Performance quoted represents past performance, which is no guarantee of future results. Investment return and principal value will fluctuate, so you may have a gain or loss when shares are sold. Current performance may be higher or lower than that quoted.
Images of NYSE Group, Inc. are used with permission of NYSE Group, Inc. Neither NYSE Group, Inc. nor its affiliated companies sponsor, approve of or endorse the contents of this program. Neither NYSE Group, Inc. nor its affiliated companies recommend or make any representation as to possible benefits from any securities or investments.
SSGA Luxembourg SICAV UCITS
State Street Global Advisors Luxembourg SICAV is an open-ended investment company with variable capital having segregated liability between its sub-funds. The Company is organised as an Undertaking for Collective Investments in Transferable Securities (UCITS) under the laws of Luxemburg and authorised as a UCITS by the Commission de Surveillance du Secteur Financier ("CSSF").
This website is directed at Qualified Investors only, as defined by Article 10(3) and (3ter) of the Swiss Collective Investment Schemes Act ("CISA") and its implementing ordinance. Certain funds may not be registered for public distribution with the Swiss Financial Market Supervisory Authority (FINMA), which acts as supervisory authority in investment fund matters, or may not have appointed a Swiss Representative and Paying Agent. For those funds which have appointed a Swiss Representative and Paying Agent, the prospectus, the articles of incorporation, the Key Investor Information Document (KIID) as well as the latest annual and semi-annual reports may be obtained free of charge from the Swiss Representative and Paying Agent, State Street Bank International GmbH, Munich, Zurich Branch, Beethovenstrasse 19, 8027 Zurich, or at www.ssga.com, as well as from the main distributor in Switzerland, State Street Global Advisors AG ("SSGA AG"), Beethovenstrasse 19, 8027 Zurich. For those funds which have not appointed a Swiss Representative and Paying Agent, please observe that the funds are open to Qualified Investors at the exclusion of Qualified Investors with an opting-out pursuant to Art. 5(1) of the Swiss Federal Law on Financial Services ("FinSA") and without any portfolio management or advisory relationship with a financial intermediary pursuant to Article 10(3ter) CISA ("Excluded Qualified Investors"). For further information and fund documents please contact SSGA AG.
You should obtain and read the sales prospectus and relevant Key Investor Information Document (KIID) prior to investing, which may be obtained by clicking here. These include further details relating to the SSGA Luxembourg SICAV funds, including information relating to costs, risks and where the funds are authorised for sale.
SSGA LPLC UCITS
State Street Global Advisors Liquidity Public Limited Company ("the Company") is an umbrella type investment company with variable capital having segregated liability between its sub-funds. The Company is organised as an Undertaking for Collective Investment in Transferable Securities (UCITS) under the laws of Ireland and authorised as a UCITS by the Central Bank of Ireland.
You should obtain and read the sales prospectus and relevant Key Investor Information Document (KIID) prior to investing, which may be obtained by clicking here. These include further details relating to the State Street Global Advisors Liquidity Public Limited Company funds, including information relating to costs, risks and where the funds are authorised for sale.

redpajama_set_name: RedPajamaCommonCrawl


text:
Home › All › Agatha Christie Close Up: A radio investigation into the Queen of Crime (BBC Audio)
Agatha Christie Close Up: A radio investigation into the Queen of Crime (BBC Audio)
A fascinating collection of archive radio programmes focussing on the life and work of the bestselling crime author, nicknamed The Queen of Crime " Agatha Christie
A fascinating collection of archive radio programmes on the life and work of crime fiction s grande dame. Agatha Christie published 66 detective novels and 14 short story collections, but to the public she remained an enigmatic figure.
These BBC radio programmes look at the woman behind the books.
Release Date: N/A
Barnaby Rudge - Charles Dickens (1960) (DVD)
Sale price £7.99 £7.99 Regular price £19.99 £19.99 Save £12
Dr Finlay's Casebook: Collectors Edition (21 DVD)
Sale price £47.99 £47.99 Regular price £199.99 £199.99 Save £152
BBC's Dombey and Son - Charles Dickens (1969) (DVD)
The Glittering Prizes: The Complete Series [DVD]
The Lady In The Van (DVD)


text:
Q: Cypher init script Neo4j 4.2 docker not working I am trying to refer to this link of documentation: https://neo4j.com/labs/apoc/4.2/operational/init-script/
This is my docker command:
docker run --rm \
--env NEO4J_AUTH="neo4j/test" \
--env NEO4JLABS_PLUGINS='["apoc"]' \
--env NEO4J_apoc_export_file_enabled="true" \
--env NEO4J_apoc_import_file_enabled="true" \
--env NEO4J_apoc_import_file_use__neo4j__config="true" \
--env NEO4J_dbms_directories_import="/" \
--env NEO4J_apoc_initializer_neo4j_1='CALL apoc.cypher.runSchemaFile("file:////var/lib/neo4j/db_init_scripts/db_ddls.cypher");' \
--env NEO4J_apoc_initializer_neo4j_2='CALL apoc.cypher.runFile("file:////var/lib/neo4j/db_init_scripts/db_schema.cypher");' \
--name neo4j \
neo4j:cus

where neo4j:cus is my custom image where I copied the required cypher files into neo4j:4.2 image
My db_ddl.cypher has create indexes:
CREATE CONSTRAINT idx_person_unq IF NOT EXISTS ON (p:Person) ASSERT p.name IS UNIQUE;

My db_schema.cypher has schema creation:
MERGE (p:Person {name: "Inital Person"});

When I try to start the container, I get below message:
Unrecognized setting. No declared setting with name: apoc.initializer.cypher.1
Unrecognized setting. No declared setting with name: apoc.initializer.cypher.2

When I try to use, older version of environment variables:
--env NEO4J_apoc_initializer_cypher_1='CALL apoc.cypher.runSchemaFile("file:////var/lib/neo4j/db_init_scripts/db_schema.cypher");' \
--env NEO4J_apoc_initializer_cypher_2='CALL apoc.cypher.runFile("file:////var/lib/neo4j/db_init_scripts/db_ddls.cypher");' \

I get this:
Unrecognized setting. No declared setting with name: apoc.initializer.cypher.1
Unrecognized setting. No declared setting with name: apoc.initializer.cypher.2

But when I try to run only one cypher:
--env NEO4J_apoc_initializer_cypher='CALL apoc.cypher.runSchemaFile("file:////var/lib/neo4j/db_init_scripts/db_ddls.cypher");' \

Then it works.
This is how my conf/neo4j.conf looks:
root@4f8955759b52:/var/lib/neo4j# grep apoc conf/neo4j.conf
#dbms.security.procedures.allowlist=apoc.coll.*,apoc.load.*,gds.*
apoc.initializer.neo4j.1=CALL apoc.cypher.runFile("file:////var/lib/neo4j/db_init_scripts/db_schema.cypher");
apoc.initializer.neo4j.0=CALL apoc.cypher.runSchemaFile("file:////var/lib/neo4j/db_init_scripts/db_ddls.cypher");
apoc.import.file.use_neo4j_config=true
apoc.import.file.enabled=true
apoc.export.file.enabled=true
dbms.security.procedures.unrestricted=apoc.*

Can anyone point what I am missing so that I can run both creation of indexes as well as initialize some schema as well?
Thanks

A: Well this behavior works only when you create a separate apoc.conf file and place it beside neo4j.conf
my apoc.conf now looks like this:
apoc.initializer.neo4j.1=CALL apoc.cypher.runSchemaFile("file:////var/lib/neo4j/db_init_scripts/db_ddls.cypher")
apoc.initializer.neo4j.2=CALL apoc.cypher.runFile("file:////var/lib/neo4j/db_init_scripts/db_schema.cypher");

And log files have outputs:
2021-05-26 18:51:06.068+0000 INFO  [neo4j/c0fb7489] successfully initialized: CALL apoc.cypher.runSchemaFile("file:////var/lib/neo4j/db_init_scripts/db_ddls.cypher")
2021-05-26 18:51:06.882+0000 INFO  Remote interface available at http://localhost:7474/
2021-05-26 18:51:06.892+0000 INFO  Started.
2021-05-26 18:51:08.091+0000 INFO  [neo4j/c0fb7489] successfully initialized: CALL apoc.cypher.runFile("file:////var/lib/neo4j/db_init_scripts/db_schema.cypher");

redpajama_set_name: RedPajamaStackExchange


text:
Cars should emit under 95g/km by 2020, says EU Commission
by Leon Poultney
THE EUROPEAN COMMISSION – the EU body responsible for implementing Europe-wide legislation – has proposed an emissions limit of 95g/km for passenger vehicles by 2020.
Under the strict targets, drivers are likely to save an estimated £3,300 over the lifetime of their cars, according to a joint report from consultancies Cambridge Econometrics and Ricardo-AEA.
The recommendations have come in a bid to sustain the competitiveness of European car makers in the wake of President Barack Obama's demand that US manufacturers hit 93g/km by 2025.
The report suggests that drivers could save around £3,300 over the lifetime of their cars.
Vehicle innovations required to meet the emissions targets would add around £1,000 to the list price of a car but drivers would save an estimated £350 a year in fuel costs.
It is also estimated that between 350,000-450,000 new jobs will be created due to increased expenditure on vehicle technology.
Improvements, such as stop-start and light-weight body panels are already available, with the latest Ford Focus ECOnetic already meeting the proposed emissions standard.
The proposals have not won universal support, with German MEPs in particular fearing the restrictions may impact negatively on their domestic market, of which larger, premium cars form a large percentage.
The European car makers' association ACEA has also warned of harm to manufacturers. Speaking to the BBC, a spokesman said: 'Price is the number-one factor motivating a customer's purchasing decision. In a sector where margins are narrow and consumers have a wide range of choice, even a slight relative price rise can make a manufacturer's range uncompetitive.'
However, some manufacturers have already committed to the proposed limit. Volkswagen has already announced its aims to reduce fleet CO2 emissions to 95g/km by 2020 in a bid to be the world's most environmentally sustainable car maker.
Car Dealer iPad App – fully updated and functional again!
iVendi: Dealers should 'consider going deskless'


Simply visit https://tr.signup.servcorp.net and follow the simple steps to join online. Our secure website uses Verisign - Symantec SSL encryption to ensure information is protected.
Can I have virtual pause during my 12 month committed service agreement?
You can make a pause maximum 3 months in a year, unless you didn't get your company's legal address registered on our address. You may contact your Account Manager for the other terms and conditions.


text:
Q: R order observations across columns I have a list of households, and the dates that they moved into a new ZIP Code. A small segment is as follows:
ADD0 <- as.Date(c("2008-07-01", "1998-07-01", "2001-11-01", "1997-08-01"), format="%Y-%m-%d")
ADD1 <- as.Date(c(NA, "2001-09-01", "2002-03-01", NA), format="%Y-%m-%d")
ADD2 <- as.Date(c(NA, "1992-09-01", "2001-09-01", "2007-12-01"), format="%Y-%m-%d")
ZIP0 <- as.character(c(30126, 30345, 30068, 30253))
ZIP1 <- as.character(c(NA, 30263, 31064, NA))
ZIP2 <- as.character(c(NA, 30345, 30067,30062))
DF <- data.frame(ADD0, ZIP0, ADD1, ZIP1, ADD2, ZIP2)
> DF
        ADD0  ZIP0       ADD1  ZIP1       ADD2  ZIP2
1 2008-07-01 30126       <NA>  <NA>       <NA>  <NA>
2 1998-07-01 30345 2001-09-01 30263 1992-09-01 30345
3 2001-11-01 30068 2002-03-01 31064 2001-09-01 30067
4 1997-08-01 30253       <NA>  <NA> 2007-12-01 30062

So house 2 moved in July '98, September '01, and September '92. My problem, as you can see, is that the dates are not necessarily in the correct order, and I need them to be. The only way I can see to do this is to loop through the dataset and write my own sort algorithm, something I have very little experience with. Efficiency is also important, because I have 450k observations.
Has anybody done this kind of thing before? Any tips? Is there a clean solution that I haven't been able to find?

A: Using the base reshape package, i would add a column house then reshape the data long.  Then order it.
DF$house <- row.names(DF)
df.long <- reshape(DF,
                   idvar='house',
                   varying=list(c('ADD0', 'ADD1', 'ADD2'),
                                c('ZIP0', 'ZIP1', 'ZIP2')),
                   v.names=c('add', 'zip'),
                   timevar=NULL,
                   direction='long')
df.long <- df.long[order(df.long$house, df.long$add),]

    house        add   zip
1.1     1 2008-07-01 30126
1.2     1       <NA>  <NA>
1.3     1       <NA>  <NA>
2.3     2 1992-09-01 30345
2.1     2 1998-07-01 30345
2.2     2 2001-09-01 30263
3.3     3 2001-09-01 30067
3.1     3 2001-11-01 30068
3.2     3 2002-03-01 31064
4.1     4 1997-08-01 30253
4.3     4 2007-12-01 30062
4.2     4       <NA>  <NA>
>

A: A loop based solution that is probably pretty slow, but keeps your format.
DF <- data.frame(ADD0, ZIP0, ADD1, ZIP1, ADD2, ZIP2, stringsAsFactors = F)
DF2 = DF

for (i in 1:nrow(DF)){
  DF2[i,] =  DF[i,
    rep(order( DF[i,1:(ncol(DF) / 2) * 2 -1])*2, each = 2) + (-1:0)]
}

I agree with the other answerer though. I think the core cause of difficulty here is the way the data is being stored here, which is pretty unhelpful to work with.


High frequency vibrating screens are the most important screening machines primarily utilised . and nonferrous metals ores (e.g. lead, zinc, gold, silver and industrial sand etc . In the mineral processing industry, equipment often has to be moved to .. Another new development is the fabrication of Polyweb urethane screen.
Gold Mining Ball MillSmall Scale Process Forged Steel Gold Mining Ball Mill . 2013 new type hydraulic impact crusher in mining area . China sand mining machine price mineral separator circular vibrating screen . Silica Sand, Philippines Silica Sand Suppliers Directory on mining ball mill machines used in glod mines .
180 products SL 200 vibration gold panning machine Vibration screen . Auxiliary equipment in ore dressing line: 1 Trough Feeder or Vibrating Feeder: feeding.
Placer Gold Mining Equipment Gold Trommel Machine Price , Find Complete Details . Quick Details. Condition: New. Type: Gravity Separator. Production Capacity: . SupplyAbility: 20 Set/Sets per Month gold trommel screen machine .. Peru, Costa Rica, USA, Vietnam, Indonesia or, Malaysia, India, Philippines, Pakistan,.
Gyro screens vibro sieves shaker machine, Thermal Engineering .
Oct 13, 2014 . Screening, sifting, classification, grading oversize or undersize, . Vibro sieve Shaker Machine, Vibrosieve Shaker Machine, Vibrating Screen,.
Tags: Inclined Vibrating Screen Machine Sand Mining Machinery Vibrating Screen 4 . gold mining equipment hot vibrating sieve classifier reasonable price ore dressing . . sand vibration machine, vibro sand screening machine for Philippines . . Xinhai is a stockholding high and new technology enterprise to provide the.


text:
Q: Doubt regarding closed form of $\sum_{k=1}^{n}\text{exp}\left(k\left(\frac{2\pi i}{n}\right)\right)$
Value of the SUM $$\sum_{k=1}^{n}\text{exp}\left(k\left(\frac{2\pi i}{n}\right)\right)$$

We can rewrite it as $$\sum_{k=1}^{n}\text{exp}\left((2\pi i)\frac{k}{n}\right)\Rightarrow \sum_{k=1}^{n}\left(e^{2\pi i}\right)^{\frac{k}{n}}$$

Now , as $$e^{\pi i}=-1$$ squaring both sides $$\color{red}{e^{2\pi i}=1}$$

So finally $$\sum_{k=1}^{n}1^{\frac{k}{n}}=n$$
Is this correct ? and what'll be the value of $$\mathfrak{Re}\left(\sum_{k=1}^{n}\text{exp}\left(k\left(\frac{2\pi i}{n}\right)\right)\right)$$

A: No, we can not do that. For example $(-1) = e^{i\pi} = (e^{2i\pi})^{\frac12} \ne 1$.
In general for a complex number $z$, $$1^z \ne 1$$
Here in your case
the equation $z^n = 1$ has exactly $n$ solutions and one of the solution is $z_1 =e^{\frac{2 \pi i}{n}}$ (ofcourse $z_0=1$ is a solution). So when you write
$$1^{\frac1n}$$ in $\mathbb{C}$, it is not clear to which root that you are referring to.
To solve the above problem you need to recognise that the summation is in the form $$\sum_{k =1}^{n} r^k$$  where $r =e^{\frac{2 \pi i}{n}}$
which is a finite geometric series.

A: This way is not correct since $\left(e^{2\pi i}\right)^{\frac1n}$ has multiple solutions, we need to use instead
$$\sum_{k=1}^{n}\left(e^{\frac{2\pi i}n}\right)^{k}$$
then by geometric series, for $n > 1$ we obtain
$$\frac{e^{\frac{2\pi i}n}-e^{\frac{2\pi i(n+1)}n}}{1-e^{\frac{2\pi i}n}}= e^{\frac{2\pi i}n} \frac{1-e^{2\pi i}}{1-e^{\frac{2\pi i}n}}=0$$
See the related

*

*Sum of nth roots of unity

A: Consider the polynomial $x^{n} -1$.
The roots of this polynomial are precisely $\exp(\frac{2ki\pi}{n})$
For $k=1,2,....n$.
So what is the sum of roots of this polynomial?.
By vieta's formula it is $\frac{-\text{coefficient of}\, x^{n-1}}{\text{coefficient of}\,x^{n}}$.
As you can see the coefficient of $x^{n-1}$ is $0$.
So sum is $0$.


This Onam, you have yet another reason to visit Munnar. The Cowboy Park built by Fun Factory in collaboration with Kerala Hydel Tourism is now accessible to visitors. The amusement park offers a variety of fun, sports and adventure activities for children as well as adults.
The Cowboy Park is in the Mattuppetty boat landing area. Chief attractions include fun rides, archery range, cricket stimulator and paintball shooting range. In addition to these, there are 10 carnival games. There is a restaurant inside the park with ample car parking facilities. The park is built in the land owned by KSEB.
For details call: 9952 44490 or 94470 81333.


JANET Indian Remy Human Wet & Wavy Weave Hair - RIPPLE DEEP 12"
Each INDIAN REMY cuticle was carefully inspected by quality control experts. Our hair is collected only from the best and healthiest stands in the world.
Our hair is assembled by a special technique that secures INDIAN REMY's hair. To prevent INDIAN REMY's hair from shedding; our wefts are reinforced and handled with the up most care.
Maintenance of INDIAN REMY hair is dependent on the style you intend for your hair. We recommend you consult your stylist for specific maintenance instructions.
Please do not dye INDIAN REMY hair. When in doubt please contact your local beautician. Inspect & de-tangle hair before washing. Make sure you do not twist or rub hair. Apply mild conditioner. Use a dry towel and gently pat down the hair. Do not roll hair. Use blow-dryer as recommended by your stylist. If your hair has bonding glue, do not apply blow-dryer over it.
Ideal temperature range for curling is between 260F and 460F. The curl is tighter as the temperature gets higher. Our stylist recommends 380F as an ideal for curling and straightening.
Straight INDIAN REMY HAIR can achieve a beautiful wavy look by doing the following.
* Dip the hair in water until thoroughly wet.
* Squeeze water our gently with a towel.
* Do not use comb or brush while hair is wet.
* If there is excess water, gently use hands to squeeze dry the hair.
* Leave hair on wig stand to dry.


Have you ever actually been in a completed house that doesn't have some form of window sills installed? Chances are that you never have. They're such a vital part of every kind of modern dwelling that you'll even see them in most manufactured housing units. About the only time you'll find a place that lacks window sills of some sort is if a contractor is currently in the process of redoing the walls.
While they might be very small in many homes, you'll be able to see at least some type of structure no matter what. There are four big reasons houses need to have these ubiquitous treatments.
If this isn't a good enough reason, we're not sure what is. Keeping water away from any structure is the top priority for window sills and may very well be one of the reasons why dwellings are built in the first place. Window sills are a necessary part of the construction building project. Without them, rain and snow can seep in through the windows and rot out your wood structure. If your dwelling is not built with wooden frames, then your interior might be lined with drywall. If water creeps into the window sill, it could breakdown the drywall causing mold build-up and can fester behind painted walls for years.
Mold is a dangerous substance to have festering in a home. Some people are a little more sensitive to it than others. Mold can cause a number of physical irritations to the throat, eye, and skin, leading to coughing or wheezing, and stuffiness—symptoms of a common cold. According to the Centers for Disease Control and Prevention states that immune-compromised people and those with chronic lung illness are more prone to get serious infections in their lungs when exposed to mold.
It might seem a bit extreme to mention chronic illness when discussing window sills, but it really isn't. This is the seriousness of what can happen if you don't install window sills in your build. It's just as important as shingles on a roof. Window sills serve as added insurance that your build will last longer.
Window sills are used at the bottom and top of a window structure. As water drizzles down a dwelling, the upper window sill catches it and directs it away from the structure. The water will either spill on the side of a window sill or over it, keeping it from seeping through and ruining the interior structure of a build.
Read our article about the "Best Material for Window Sills" here.
2. Window sills help hold a window in place.
Window sills are necessary because they are a part of a building's structure. They serve as the framing of the window to keep it in place. Without a window sill, the opening of that window would sway and shift as the foundation settles. This could jeopardize the integrity of an installation causing cracks and an unleveled structure. The window sill acts as a brace to reinforce the wall. If nothing else, then incorporating window sills are an absolute must when it comes to setting a building budget.
3. Window sills can be decorative.
In the earlier builds, window sills were made of wood because it was easier and less expensive to get. The downside to this is that because wood is a living organism—a plant to be exact, it will eventually decay. And as a plant that has been removed from the ground, it then becomes the perfect burrowing ground for carpenter ants, grubs, and worse, termites if not treated.
Builders eventually got smart and started treating the wood to make it last longer, but time usually gets the best of this type of material and a replacement is inevitable. This is where other types of building materials come into play bringing about more options, and marble is considered one of those options—the most popular building materials for window sills to date, not only because it's more durable, but also it's visually attractive.
Marble window sills are also an organic material, but it won't break down or decay like wood because of how it is made. Marble is created from an immense amount of heat that's hot enough to melt limestone and other surrounding minerals. Marble is water and fireproof, and with the proper sealant, it won't stain. Another great feature about marble that makes it so decorative is the variety of colors.
Stonexchange, a wholesale manufacturer and wholesale distributor of marble window sills supplies many marble dealers, retailers, contractors, and developers around the world. So we have a good idea of what's most popular in the market, and our customer service department can recommend the best kind of marble window sills for your next build. We're also available for quality service if you just need to restock the supply in your warehouse.
You can read more about how decorative window sills can be in our other article, "Why Great Looking Window Sills Make a Home More Stylish!" here.
4. Because You Have To!
As a building contractor, there is no choice of whether or not you should install them. It's absolutely necessary, whether you understand the reasoning behind them or not. Buyers expect it and it's as common as the front door!
Where you do have a choice is selecting what kind of window sill to install in your builds. You can go the less expensive route and go with the treated wood, or you can upgrade your entire stock—and even your brand by installing beautiful luxury marble window sills.
You have the 4 main reasons. Now all you have to do is make one call – to contact Stonexchange!
Contact a Stonexchange representative to learn about possible discounts for bulk order and ask any questions you might have about marble window sills, thresholds, or soap caddies.


Launch your app under 100 days.
The digital products you love are the results of thousands of small iterations leading to the result that feels natural. Everything starts with launching a first version and gaining sufficient user insights to improve it step by step. Our Lean Startup approach enables us to deliver an application within a 100 days.
We take into account the complexity of your project or existing service, but most importantly, we conduct research upfront, before starting to build anything. This enables us to identify what's the most important for your users, and to concentrate our efforts into what matter's the most: the product's added values.
Our Lean approach reduces a maximum of initial overload by setting aside the features which aren't adding significative value to your application's first version. If your application offers multiple services, we will focus on what's called the MVP (Minimum Viable Product) in the first 100 days, and will develop the rest later where it belongs: in the growth phase.
Within our Lean Startup approach, the MVP isn't a project's first step, rather, it is a milestone in a larger approach: identifying and focusing on what's essential from the start, by challenging the concept even before it is developed.
The MVP has a goal: to concentrate the core values which will guide your application to success. The main objective is straightforward: to propose the adequate solution to your user's problem. Gathering feedbacks along the way is crucial to confirm the orientation of your project, and if this isn't the case, these feedbacks will give precious informations on how to improve your plans in order to pinpoint what will get your users engaged with the next few evolutions.
We support and consult you all the way up to the launch of your MVP. By analysing your users needs and desires we establish strategies together to focus on whats essential to the first version of your application. This is what sets all the chances of your project to succeed, fast.


text:
Some Exciting New Dork News...and a Few Reviews
I don't have an actual bookish bucket list, but if I did "working at a bookstore" would be near the top. And now I can (pretend to) cross it off! A new indie called RoscoeBooks is opening just a few blocks from where I live here in Chicago, and despite the fact that this is damn near akin to hiring an alcoholic to bar tend, the owner is graciously allowing me to work there a few hours a week. I couldn't be more excited! The store opens this Saturday, Nov. 22 — if you're in Chicago, come say 'hello.' I'll be the one with ridiculous perma-grin-goofy-happy smile on my face.
And but, one of the reasons I'm super excited to be a bookseller is, yes, to be able to recommend books I love to other people, but also to learn more about what other people are reading that fall outside my immediate comfort zone. Another reason I'm excited is working at a bookstore will only make it more apparent that there's always something to learn about books. So in some ways, this is selfish excitement, because I'll get to discover books I may have otherwise missed. And that's already happened just in the last week as a result of talking with the other booksellers (see below) and helping to shelve (I assume it's natural to talk to the authors as you shelve their books, right?). So anyway, yeah — I'm stoked. This...will be fun.
And so, here, have some reviews:
Submergence, by J.M. Ledgard — If you've never heard of this book, don't worry — I hadn't either until a few weeks ago. But the new owner of RoscoeBooks recommended this, and I read it in about two sittings. It's a short novel about a guy named James who is a British spy and gets kidnapped by Islamic extremists in Somalia. It's also about a woman named Danny who is a biomathematician — she studies microbial life in the deepest depths of the ocean. And finally, it's about how the two met, and how they discuss life, and why we're all here ("We're nature's brief experiment with self-awareness," Ledgard writes — a mind-blowing idea, when you really think about it.), and chance and luck, and art and literature, and it's just fantastic. The story's told in brief snippets, alternating perspectives between Danny and James, and between the present day, and when the two met at a French hotel on the Atlantic coast. If you've read and enjoyed Anthony Doerr's All The Light We Cannot See, I think you'll love this, too.
The Book of Strange New Things, by Michel Faber — This big, sprawling novel has one of the more inventive premises of any novel I've read in awhile. It's about a Christian missionary named Peter who is hired by a mysterious corporation called USIC to travel to a distant planet (which humans have dubbed Oasis) to preach the Bible to the native population (which Peter calls Oasans). Peter must leave his beloved wife Bea— who was his savior when he was a drug and alcohol addict, and who was his reason for his being "born again." Life on Earth in general, and his wife Bea's life specifically (as he learns by communicating with her via a rudimentary emails machine — and Faber includes these missives at great length), begin to deteriorate and Peter feels helpless, but has success with the Oasans. Peter is the second minister to visit Oasis, and the Oasans, who refer to themselves as Jesus Lover Five, Jesus Lover Thirty, etc, are eager to learn more about Jesus. The novel, though often a bit too deliberate, is an interesting reflection on the egoism inherent in particular religious doctrine (being so sure you're right and everyone else is wrong) specifically, but humanity in general. When you finally see the whole picture —why the Oasans want a Christian minister and to learn about "The Book of Strange New Things" (the Bible) — you'll realize it's a conclusion that matches the ingenuity of the whole plot itself. But it's just a really long walk to get there.
A Map of Betrayal, by Ha Jin — I loved Ha Jin's novel War Trash, but I was only so-so on this one. It's the story of a Chinese spy who spends the last half of the 20th century in the U.S. taking an American wife and working at the CIA. It's also the story of his daughter, who in present day, is trying to learn the truth about her father and the rest of his family — her father had a whole other family back in China before he came to the U.S. It's a short, brisk novel that I thought actually read more like an outline for a novel than a novel itself. What's here is intriguing, but it just felt too slight.
Mozette November 20, 2014 at 6:11 AM
Woot! A bookaholic working in a book store!!!!
Yay! It's actually happened that one of us has joined in and been allowed to drool over the books for once! :D
Way to go!!!! :D
Greg Zimmerman November 20, 2014 at 9:09 AM
Leah @ Books Speak Volumes November 20, 2014 at 8:24 AM
Congrats on the job!
thecuecard November 27, 2014 at 8:57 PM
Congrats on the bookstore job. Sounds like fun
How To Build a Girl: Assault on Cynicism


Copper- and borate-based preservative treatments have proven effectiveness, but structural plastics are more durable.
Synopsis: When copper chromated arsenate (CCA) was eased off the market at the end of 2003 due to fears about its toxicity, builders needed to find new sources for rot-resistant structural lumber. As contributing editor Scott Gibson has discovered, the industry has responded by developing three new types of rot-resistant framing materials. The new materials include lumber treated with alkaline copper quaternary (ACQ) or copper azole (CA); wood treated with borate, a naturally occurring mineral salt; or fiberglass-reinforced plastic lumber (FRPL), made from recycled plastics. The article includes a sidebar about new compounds and organic treatments in development.
Following a systematic sequence will ensure that your wall framing comes together without any mistakes.


The welded steel, double-side wall construction allows for exceptional structure and perfect support for storage needs.
Features one 4.4" tall full-width drawer ideal for long handle tools, one 6" tall x 22.2" wide drawer, six 2.9" tall x 22.2" wide drawers and two 9.1" tall x 22.2" wide drawers ideal for various sized tools, such as hammers, mallets and power tools.
Base unit supports stacking of the 10-Drawer 52" Tool Chest to create a 2-piece stackable tool chest for maximum mobile tool storage.
The oval-shaped tubular steel Reversible Side-Push Handle is designed to fit your hands comfortably and provide superior control while pushing the Roll-Away. The Reversible Side-Push Handle can be mounted to either the left or right side of the cabinet, depending on your needs.
Rated load up to 1,000 lbs per Roll-Away, based on lab test of 4,000 lbs per Roll-Away. 4.4" tall x 47" wide drawer rated to 75 lbs, and all other drawers rated to 50 lbs.
For the life of the product, when used and maintained according to instructions attached to or furnished with the product, Gladiator® GarageWorks will pay for repair or replacement of the prooduct due to defective materials or workmanship.


text:
Tag: budget travel
After the World's Biggest Recession, It's Solo Travellers That Find the Deals
Hoteliers have rejoiced about the increase in occupancy rates. With a twenty percent surge in the number of booked hotel rooms throughout the first half of 2010 and an increase in travel industry spending, it seems as if Britain's travel-friendly population was back to its old habits. But there's one demographic that's missed out on the industry-wide praise: internet-savvy solo travellers.
Hotel aggregator firms like Priceline and its Pacific subsidiary Agoda have helped solo travellers find low-cost room deals and fill gaps in hotel inventory, industry journalists claim. The surge in recent bookings is primarily due to families and business travellers, although individual bookings have made up a significant portion of the global accommodation market's revenues.
Most travellers still book their flights and accommodation using an agency, primarily due to the cheaper fares and hotel rates on offer. But a growing number of solo travellers are eschewing an appointment with the travel agent in favour of an online booking, potentially saving themselves money in the process. Services like Priceline top popularity lists, along with Agoda and Orbitz.
There's also been an increase in the number of travellers booking combined accommodation and flights through an aggregator-turned-airline. Asian low-cost carrier AirAsia has turned combined bookings into an art, encouraging solo travellers to book hotels using their website by offering a collection of coupon codes and special discounts.
While upsells, cross-sells, and special promotions are far from new in the online travel industry, their renewed presence is certainly a good sign for the travel industry. Splashes of darkness are visible in the windows of even the world's most popular hotels, indicating that there's still room available at below-cost rates for those with an innovative approach and sufficient tech savviness.
Author Staff WriterPosted on September 1, 2010 September 2, 2010 Categories HotelsTags budget travel, Hotels
AirAsia's Rapid Expansion: How One Budget Airline is Winning Asia
Malaysian low-cost carrier AirAsia has taken the world by storm since commencing operation in 1996. Over the last decade, the airline has won a considerable amount of business throughout SE Asia and its native Malaysia, winning customers that prefer a low-cost alternative to the high-end fares and expensive airlines that are ubiquitous throughout the region.
What's most impressive, however, is that the airline has achieved a dominant position within the region's air travel industry in little more than a decade. AirAsia's rapid growth is amazing from a business standpoint and from a historical point, with large companies like Malaysia Airlines and well-known Singapore Airlines formerly dominating travel within the airline's operating region.
Its customer-first strategy has won the airline praise from industry groups, with AirAsia recently named the world's 'best low-cost airline' at the SkyTrax World Airline Awards. Thanks to its slick marketing operations and incredible level of customer loyalty, the airline has achieved a position that's unique amongst low-cost airlines: few AirAsia customers use other airlines within Asia.
For a low-cost carrier, that's quite an achievement. While Europe's low-cost airlines are forced to fight off negative publicity and compete based on price alone, AirAsia has formed a unique spot amongst its competitors as a low-cost airline with immense customer loyalty. During the airline's recent 'Mind Blowing Fare' promotion, over 500,000 tickets were sold during in a single day.
The successful formula has lead to other air travel companies in the region taking notice. Tiger Airways, a low-cost carrier based in neighbouring Singapore, plans to join forced with high-end carrier Thai Airways for a competing service. Given AirAsia's promotional savvy and incredible level of customer loyalty, the challenge seems like one that could spark a regional air revolution.
Author Staff WriterPosted on September 1, 2010 September 2, 2010 Categories TravelTags AirAsia, Airlines, budget travel
Exploring Tokyo — The World's Biggest City — on a Backpacker Budget
There's no city quite like Tokyo. The Japanese capital is both the biggest city in the world and one of its most culturally interesting, combining three-hundred-year-old temples and skyscrapers, rich cultural gems with cutting-edge technology. When it comes to experiencing high-tech Asia, there's truly no real alternative to a quick trip through Japan's mega-metropolis.
But Tokyo has a semi-deserved reputation for expense, particularly for travellers. Ranked as one of the world's most expensive cities for expatriates, the megacity is often thought of as a destination for those with Herculean budgets. We don't think so – with the right spending strategy and a bit of calculated frugality, the Japanese capital can be a good budget travel destination.
Where to start? Pick a hotel that's outside of the city centre. Tokyo has the world's most effective public transport system and it's pointless to ignore it by booking into a central hotel. Provided your room is within walking distance of a train station, it's no less convenient than one in Shibuya or the Shinjuku business district.
Don't eat out, eat up. Tokyo's ground floor restaurants tend to be overpriced and disappointing, with basic plates of ramen attracting five-star prices. Find better prices and better quality by walking up a floor or two. Third and fourth-floor restaurants in Tokyo tend to be less expensive, more friendly, and less crowded, giving you a better travel experience and better food.
Finally, learn basic Japanese. Tokyo is expensive and impersonal at first, but with a basic collection of Japanese phrases on your side it quickly becomes a manageable city. Arm yourself with a concise phrasebook and take note of some simple Japanese sentences, particularly ones related to housing or eateries. Japanese people love to help you out, provided you're willing to put in some effort first.
Author Staff WriterPosted on September 1, 2010 September 2, 2010 Categories City BreaksTags budget travel, city breaks, Tokyo


text:
The Federal Administration in treecrumb format
The federal Council admin.ch
FDHA
FOPH: Federal Office of Public Health
FOC: Federal Office of Culture
FSVO: Federal Food Safety and Veterinary Office
FSIO: Federal Social Insurance Office
FSO: Swiss Federal Statistical Office
SFA: Swiss Federal Archives
MeteoSwiss: Federal Office of Meteorology and Climatology
Swissmedic: Swiss Agency for Therapeutic Products
FOGE: Federal Office for Gender Equality
FOPH
Treatment abroad for policyholders resident in Switzerland
Easy-to-read language
Federal Office of Public Health FOPH
Terms A-Z
The FOPH
Medicine & research
Strategy & policy
Laws & licenses
Figures & statistics
Insurancescurrent page
Benefits and tariffs
Treatment abroad
Back Back Benefits and tariffs
Treatment abroad for policyholders resident in Switzerland selected
Treatment abroad for policyholders resident abroad
In certain cases, persons resident and insured in Switzerland can be treated abroad. The conditions for reimbursement of the costs vary, depending on the type of service and the country in which it is provided.
Temporary stay in an EU/EFTA country
During a temporary stay in an EU/EFTA country, policyholders can be treated if they present their European Health Insurance Card (EHIC), which is to be found on the back of the Swiss health insurance card. In the event of illness, accident or maternity, policyholders are then entitled to receive all benefits in kind considered medically necessary given the type of treatment and expected length of their stay. The list of reimbursable items is subject to the law of the country in which the treatment is carried out. Co-payment is subject to the regulations of the country concerned and is generally payable directly. Co-payment in Switzerland is then not applicable. Nor is co-payment in an EU/EFTA country taken into account for the Swiss deductible or retention fee.
If policyholders do not have their EHIC with them, their health insurer may issue a temporary certificate.
For more information, see "Temporary stay in an EU/EFTA country" (available in French/German/Italian) on the website of the Common Institution under the KVG (Swiss liaison body).
Temporary stay in a non-EU/EFTA country
During a temporary stay in a country outside the EU/EFTA, the costs of emergency treatment for illness or accident (in cases where a return to Switzerland is not possible for medical reasons) will be reimbursed up to a maximum of twice the amount that would be paid if the treatment were provided in Switzerland. In the case of inpatient treatment, this means that the insurer will reimburse no more than 90% of the costs that would have arisen for hospitalisation in Switzerland. This is because, in the case of hospital treatment in Switzerland, at least 55% of the costs are borne by the cantons, which is not the case for hospital stays abroad.
Other medical treatments abroad are not generally covered by compulsory health insurance.
Planned treatment abroad
In certain cases where a treatment is not available in Switzerland or waiting periods are too long, the costs may be reimbursed for these particular treatments abroad. In such cases, the policyholder's attending physician must submit an application (explaining the reasons) to the health insurer's independent medical adviser. In consultation with the latter, the insurer will decide whether the costs of the treatment abroad can be reimbursed (see the conditions specified in the information letter dated 8 April 2008 on medical treatment abroad; available in French/German).
Medicines purchased abroad
The costs of medicines purchased abroad will only be reimbursed if they are required by the policyholder because of illness during a temporary stay abroad.
Informationsschreiben vom 8. April 2008 über die medizinische Behandlung im Ausland (in German) (PDF, 450 kB, 26.05.2021)
Basisablauf für Leistungen im Ausland nach KVV 36/1 (in German) (PDF, 69 kB, 10.05.2019)
Aufenthalt in der EU/EFTA (in German, French, Italian)
SR 832.102 KVV, Art. 36 (in German)
Health insurance: Tourists abroad and globetrotters
Persons travelling abroad remain subject to insurance obligations in Switzerland.
Health and Accident Insurance Directorate
Insurance Supervision Division
https://www.bag.admin.ch/content/bag/en/home/versicherungen/krankenversicherung/krankenversicherung-leistungen-tarife/Leistungen-im-Ausland/Behandlungen-im-Ausland-fuer-Versicherte-mit-Wohnsitz-in-der-Schweiz.html
Tasks & goals
Departmental research & evaluation
Supplementary information on data use
Social media and the FOPH
Health promotion & prevention
Addiction & health
Health for children and young people (dossier)
Health in old age (dossier)
Diseases from A to Z
Infectious diseases: Outbreaks, Epidemics, Pandemics
Combating infectious diseases
Biomedical research and technology
Research involving humans
Research Involving Human Embryonic Stem Cells
Medicinal products & medical devices
Patients' rights
Military insurance
National health strategies
Political mandates & action plans
National health policy
Psychology professions
Accreditation of health professions
Foreign diplomas of health professions
Accident and Military Insurance: statistics
Chemical Exposure in the Human Body
Health equity: facts & figures
Health insurance: statistics
Health professions: statistics
Hospitals: facts & figures
Reproductive Medicine: facts & figures